Files
pip/libs/main/thread/piprotectedvariable.h

108 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \file piprotectedvariable.h
//! \ingroup Thread
//! \brief
//! \~english Thread-safe variable
//! \~russian Потокобезопасная переменная
//!
//! \details
//! \~english Template class for thread-safe variable access with mutex protection.
//! \~russian Шаблонный класс для потокобезопасного доступа к переменной с защитой мьютексом.
/*
PIP - Platform Independent Primitives
Thread-safe variable
Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIPROTECTEDVARIABLE_H
#define PIPROTECTEDVARIABLE_H
#include "pimutex.h"
//! \~english Thread-safe variable template class
//! \~russian Шаблонный класс потокобезопасной переменной
template<typename T>
class PIP_EXPORT PIProtectedVariable {
public:
//! \~english Pointer wrapper for thread-safe access
//! \~russian Обертка указателя для потокобезопасного доступа
class PIP_EXPORT Pointer {
friend class PIProtectedVariable<T>;
public:
//! \~english Copy constructor
//! \~russian Конструктор копирования
Pointer(const Pointer & v): pv(v.pv), counter(v.counter + 1) {}
//! \~english Destructor - unlocks mutex
//! \~russian Деструктор - разблокирует мьютекс
~Pointer() {
if (counter == 0) pv.mutex.unlock();
}
//! \~english Access member
//! \~russian Доступ к члену
T * operator->() { return &pv.var; }
//! \~english Access value
//! \~russian Доступ к значению
T & operator*() { return pv.var; }
private:
Pointer() = delete;
//! \~english Construct from PIProtectedVariable
//! \~russian Конструктор из PIProtectedVariable
Pointer(PIProtectedVariable<T> & v): pv(v) {}
PIProtectedVariable<T> & pv;
int counter = 0;
};
//! \~english Sets value to \"v\"
//! \~russian Устанавливает значение как \"v\"
void set(T v) {
PIMutexLocker _ml(mutex);
var = std::move(v);
}
//! \~english Lock mutex and returns reference wrapper of value. Unlock on variable destructor.
//! \~russian Блокирует мьютекс и возвращает класс-обертку на значение. Разблокирует в деструкторе переменной.
Pointer getRef() {
mutex.lock();
return Pointer(*this);
}
//! \~english Returns copy of value
//! \~russian Возвращает копию значения
T get() const {
PIMutexLocker _ml(mutex);
return var;
}
//! \~english Sets value to \"v\"
//! \~russian Устанавливает значение как \"v\"
PIProtectedVariable<T> & operator=(T v) {
set(std::move(v));
return *this;
}
private:
mutable PIMutex mutex;
T var;
};
#endif