/*! * \file CyclopsLock.h * \date 2018/07/18 * * \author Lin, Chi * Contact: lin.chi@hzleaper.com * * * \note */ #ifndef __CyclopsLock_h_ #define __CyclopsLock_h_ // for backward compatibility of Cyclops // to compile in visual studios doesn't fully support modern cpp #include "CyclopsVersion.h" #include class CSImpl; /*! \brief Wrapper of lock for compilers don't fully support modern cpp * * [Windows] * For visual studio 2010 or older version, it's implemented via CRITICAL_SECTION * For others, it equals to std::mutex * [Unix] * For gcc have no c++11 support, it's not implemented yet, as no requirement yet * For others, it equals to std::mutex * * Example: * \code{.cpp} * mylock.lock(); * // balabala, the code you want to protect * // ... * mylock.unlock(); * \endcode * * Note: it's recommended in ANY cases to use CyclopsLockGuard instead of manually call lock/unlock yourself, * since the designed work flow may be interrupted by some exceptions and you need to write unlock in every return branch. * Unless you're 100% sure you want and need to manipulate the lock yourself, DO USE CyclopsLockGuard * */ class CYCLOPS_UTILS_SPEC CyclopsLock { public: CyclopsLock(); ~CyclopsLock(); /*! Acquire the lock */ void lock(); /*! Release the lock */ void unlock(); /*! Acquire the shared lock */ void lock_shared(); /*! Release the shared lock */ void unlock_shared(); /*! Whether this lock is exclusively locked */ bool isLocked() const; private: std::unique_ptr mpCSImpl; }; /*! \brief Lock guard for CyclopsLock * * It is used to ensure a lock is always released when leave the code block * * Example: * \code{.cpp} * { * CyclopsLockGuard guard(&mylock); * // balabala, the code you want to protect * // ... * } // the lock will be released when leave the block * \endcode */ class CyclopsLockGuard { public: CyclopsLockGuard(CyclopsLock* pLock) { mpLock = pLock; mpLock->lock(); } ~CyclopsLockGuard() { mpLock->unlock(); } private: CyclopsLock* mpLock; }; /*! \brief Shared lock guard for CyclopsLock * * It is used to ensure a shared lock is always released when leave the code block * * Example: * \code{.cpp} * { * CyclopsSharedLockGuard guard(&mylock); * // balabala, the code you want to protect * // ... * } // the lock will be released when leave the block * \endcode */ class CyclopsSharedLockGuard { public: CyclopsSharedLockGuard(CyclopsLock* pLock) { mpLock = pLock; mpLock->lock_shared(); } ~CyclopsSharedLockGuard() { mpLock->unlock_shared(); } private: CyclopsLock* mpLock; }; #endif