ATL::CComMultiThreadModelクラス(リンク先はMSDNライブラリ)の実装を見ていると、もう少し今時っぽい感じにしたいなと思いました。というわけで、さくっと書いてみました。
#define _ATL_NO_AUTOMATIC_NAMESPACE #include <atlbase.h> #include <atlcom.h> #include <mutex> class ComMultiThreadModelExNoCS { public: static ULONG WINAPI Increment(_Inout_ LPLONG p) throw() { return ::_InterlockedIncrement(p); } static ULONG WINAPI Decrement(_Inout_ LPLONG p) throw() { return ::_InterlockedDecrement(p); } typedef ATL::CComFakeCriticalSection AutoCriticalSection; typedef ATL::CComFakeCriticalSection AutoDeleteCriticalSection; typedef ATL::CComFakeCriticalSection CriticalSection; typedef ComMultiThreadModelExNoCS ThreadModelNoCS; }; class RecursiveMutexForAtl { public: RecursiveMutexForAtl() {} ~RecursiveMutexForAtl() {} HRESULT Lock() { m_mutex.lock(); return S_OK; } HRESULT Unlock() { m_mutex.unlock(); return S_OK; } HRESULT Init() throw() { return S_OK; } HRESULT Term() throw() { return S_OK; } std::recursive_mutex m_mutex; }; class ComMultiThreadModelEx { public: static ULONG WINAPI Increment(_Inout_ long* p) throw() { return ::_InterlockedIncrement(p); } static ULONG WINAPI Decrement(_Inout_ long* p) throw() { return ::_InterlockedDecrement(p); } typedef RecursiveMutexForAtl AutoCriticalSection; typedef RecursiveMutexForAtl AutoDeleteCriticalSection; typedef RecursiveMutexForAtl CriticalSection; typedef ComMultiThreadModelExNoCS ThreadModelNoCS; }; |
特徴は2つです。
- インクリメント・デクリメントをコンパイラ組み込み版にした。
- クリティカルセクションの代わりに、std::recursive_mutexを採用してみた。
Windowsのクリティカルセクションは再入OKなので、それにあわせてrecursive_mutexを選びました。std::mutexやVC++のConcurrency Runtimeのcritical_sectionクラスなどもいいですね。あるいは、WindowsのCRITICAL_SECTIONを使うけど、InitializeCriticalSectionAndSpinCount関数を呼び出すようにして、スピンロックの値を指定するという改良も考えられます。
スポンサード リンク |