//----------------------------------------------------------------------------- // 用排他锁实现的并发共享数据的模板类. // 不是 dll, 没有版本号, 因此要手工编写版本号 // V1, 2013-09-03, 5.1.1 中发布, 使用 Synchronize.hpp // V2, 2018-03-02, 7.0 中发布, 改用 std::recursive_mutex 及 std::lock_guard // V3, 2020-09-30, 7.3 中发布, 删除 XDWHolder, 改用 std::unique_ptr. 同时修改了文件名 // V4, 2022-09-30, LockHolder 中, 删除 std::unique_ptr, 直接用 std::lock_guard < std::recursive_mutex > m_Lock; // 这样可以避免一次 new / delete //----------------------------------------------------------------------------- #pragma once #include #include //----------------------------------------------------------------------------- // ExclusiveHolder.tlh // 允许互斥访问一个指针对象 //----------------------------------------------------------------------------- template class ExclusiveHolder { protected: T * m_pObject; public: ExclusiveHolder (); explicit ExclusiveHolder (T * object); virtual ~ExclusiveHolder (); private: // 禁止拷贝构造函数 ExclusiveHolder (const ExclusiveHolder & h) = delete; // 禁止复制 ExclusiveHolder & operator = (const ExclusiveHolder & h) = delete; public: void Attach (T * object); T * Detach (); ExclusiveHolder & operator = (T * object); bool IsEmpty () const; void Release (); std::recursive_mutex & GetMutex () { return m_Mutex; } protected: mutable std::recursive_mutex m_Mutex; public: class LockHolder { public: LockHolder (const ExclusiveHolder * holder) : m_Lock { std::lock_guard < std::recursive_mutex > (holder->m_Mutex) } , m_Holder (holder) { assert (m_Holder); } ~LockHolder () = default; LockHolder (LockHolder && from) { m_Lock.swap (from.m_Lock); m_Holder = from.m_Holder; } private: // 可以对同一个 ExclusiveHolder 对象反复调用 Lock, 但是 LockHolder 还是不要拷贝构造了吧 // 禁止拷贝构造函数 LockHolder (const LockHolder & h) = delete; // 禁止复制 LockHolder & operator = (const LockHolder & h) = delete; public: T * As () { return m_Holder->m_pObject; } const T * As () const { return m_Holder->m_pObject; } template C * AS () { return m_Holder->m_pObject; } template const C * AS () const { return m_Holder->m_pObject; } T * operator -> () { return As (); } const T * operator -> () const { return As (); } T & operator * () { return *As (); } const T & operator * () const { return *As (); } operator bool () const { return As (); } protected: std::lock_guard < std::recursive_mutex > m_Lock; const ExclusiveHolder * m_Holder; }; public: inline LockHolder Lock () { return LockHolder (this); } inline LockHolder Lock () const { return LockHolder (this); } template auto Action (FuncType && action, Args && ... args) -> typename std::invoke_result ::type { LockHolder holder (this); return action (holder.As (), args...); } #if 0 template auto Action (FuncType && action, Args && ... args) const -> typename std::invoke_result ::type { LockHolder holder (this); return action (holder.As (), args...); } #endif };