#pragma once #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x500 #include #include #include #include #pragma comment(lib, "comsuppw.lib") namespace cg_quick { class noncopyable { private: noncopyable(const noncopyable &); const noncopyable &operator= (const noncopyable &); protected: noncopyable(void) {} ~noncopyable(void) {} }; template class locker { private: lock_t & lock_; public: locker(lock_t & lck) : lock_(lck) { lock_.lock(); } locker(const locker &r) : lock_(r.lock_) { lock_.lock(); } const locker &operator= (const locker &r) { if (this != &r) { lock_.unlock(); lock_ = r.lock_; lock_.lock(); } return *this; } ~locker() { lock_.unlock(); } }; struct nolock : public noncopyable { bool lock(int timeout = -1) { return true; } void unlock() {} typedef locker locker; locker get_locker() { return locker(*this); } }; struct cslock : public noncopyable, private CRITICAL_SECTION { cslock() { ::InitializeCriticalSection(this); } ~cslock() { ::DeleteCriticalSection(this); } bool lock(int timeout = -1) { // возможна ситуация, когда CRT уничтожает CRITICAL_SECTION, // а из другого потока происходит попытка её занятия // (в частности, такое наблюдается при завершениим программ по Ctrl-C - // при записи в лог в момент, когда удаляются различные объекты) __try { ::EnterCriticalSection(this); return true; } __except(EXCEPTION_EXECUTE_HANDLER) { } return false; } void unlock() { __try { ::LeaveCriticalSection(this); } __except(EXCEPTION_EXECUTE_HANDLER) { } } typedef locker locker; locker get_locker() { return locker(*this); } }; template class transparent_proxy : public noncopyable { T * m_ptr; transparent_proxy(); public: transparent_proxy(T * ptr) : m_ptr(ptr) {} T * operator -> () const { return m_ptr; } }; template class locking_proxy : public noncopyable { T * m_ptr; locking_proxy(); public: locking_proxy(T * ptr) : m_ptr(ptr) { m_ptr->lock(); } ~locking_proxy() { m_ptr->unlock(); } T * operator -> () const { return m_ptr; } }; template class singleton : public noncopyable { static T * pinstance_; protected: static lock_t locker_; public: static T & instance() { if (!pinstance_) { lock_t::locker guard = locker_.get_locker(); if (!pinstance_) { pinstance_ = new T(); } } return *pinstance_; } template