//! \~\file piprotectedvariable.h //! \~\ingroup Thread //! \~\brief //! \~english Thread-safe variable //! \~russian Потокобезопасная переменная /* PIP - Platform Independent Primitives Thread-safe variable Ivan Pelipenko peri4ko@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 . */ #ifndef PIPROTECTEDVARIABLE_H #define PIPROTECTEDVARIABLE_H #include "pimutex.h" //! \~\ingroup Thread //! \~\brief //! \~english Thread-safe variable template class //! \~russian Шаблонный класс потокобезопасной переменной template class PIP_EXPORT PIProtectedVariable { public: //! \~\brief //! \~english Pointer-like wrapper returned by \a getRef() while the protected value remains locked. //! \~russian Указателеподобная обертка, возвращаемая \a getRef(), пока защищенное значение остается заблокированным. class PIP_EXPORT Pointer { friend class PIProtectedVariable; public: //! \~english Copies wrapper state for access to the same protected value. //! \~russian Копирует состояние обертки для доступа к тому же защищенному значению. Pointer(const Pointer & v): pv(v.pv), counter(v.counter + 1) {} //! \~english Destroys wrapper and releases the mutex when it owns the original lock. //! \~russian Уничтожает обертку и освобождает мьютекс, когда она владеет исходной блокировкой. ~Pointer() { if (counter == 0) pv.mutex.unlock(); } //! \~english Returns pointer access to the protected value. //! \~russian Возвращает указательный доступ к защищенному значению. T * operator->() { return &pv.var; } //! \~english Returns reference access to the protected value. //! \~russian Возвращает ссылочный доступ к защищенному значению. T & operator*() { return pv.var; } private: Pointer() = delete; Pointer(PIProtectedVariable & v): pv(v) {} PIProtectedVariable & pv; int counter = 0; }; //! \~english Replaces the protected value with \a v. //! \~russian Заменяет защищенное значение на \a v. void set(T v) { PIMutexLocker _ml(mutex); var = std::move(v); } //! \~english Locks the value and returns wrapper-based access to it. //! \~russian Блокирует значение и возвращает обертку для доступа к нему. Pointer getRef() { mutex.lock(); return Pointer(*this); } //! \~english Returns a copy of the protected value. //! \~russian Возвращает копию защищенного значения. T get() const { PIMutexLocker _ml(mutex); return var; } //! \~english Replaces the protected value with \a v. //! \~russian Заменяет защищенное значение на \a v. PIProtectedVariable & operator=(T v) { set(std::move(v)); return *this; } private: mutable PIMutex mutex; T var; }; #endif // PIPROTECTEDVARIABLE_H