115 lines
3.1 KiB
C++
115 lines
3.1 KiB
C++
#pragma once
|
|
|
|
class _critical_section_base {
|
|
protected:
|
|
CRITICAL_SECTION sec;
|
|
public:
|
|
_critical_section_base() {}
|
|
inline void enter() throw() {EnterCriticalSection(&sec);}
|
|
inline void leave() throw() {LeaveCriticalSection(&sec);}
|
|
inline void create() throw() {
|
|
#ifdef PFC_WINDOWS_DESKTOP_APP
|
|
InitializeCriticalSection(&sec);
|
|
#else
|
|
InitializeCriticalSectionEx(&sec,0,0);
|
|
#endif
|
|
}
|
|
inline void destroy() throw() {DeleteCriticalSection(&sec);}
|
|
inline bool tryEnter() throw() { return !!TryEnterCriticalSection(&sec); }
|
|
private:
|
|
_critical_section_base(const _critical_section_base&);
|
|
void operator=(const _critical_section_base&);
|
|
};
|
|
|
|
// Static-lifetime critical section, no cleanup - valid until process termination
|
|
class critical_section_static : public _critical_section_base {
|
|
public:
|
|
critical_section_static() {create();}
|
|
#if !PFC_LEAK_STATIC_OBJECTS
|
|
~critical_section_static() {destroy();}
|
|
#endif
|
|
};
|
|
|
|
// Regular critical section, intended for any lifetime scopes
|
|
class critical_section : public _critical_section_base {
|
|
public:
|
|
critical_section() {create();}
|
|
~critical_section() {destroy();}
|
|
};
|
|
|
|
template<typename lock_t>
|
|
class c_insync_
|
|
{
|
|
private:
|
|
lock_t& m_section;
|
|
public:
|
|
c_insync_(lock_t * p_section) throw() : m_section(*p_section) {m_section.enter();}
|
|
c_insync_(lock_t & p_section) throw() : m_section(p_section) {m_section.enter();}
|
|
~c_insync_() throw() {m_section.leave();}
|
|
};
|
|
|
|
typedef c_insync_<_critical_section_base> c_insync;
|
|
|
|
// Old typedef for backwards compat
|
|
#define insync(X) c_insync blah____sync(X)
|
|
// New typedef
|
|
#define PFC_INSYNC(X) c_insync_<decltype(X)> blah____sync(X)
|
|
|
|
|
|
namespace pfc {
|
|
|
|
|
|
// Read write lock - Vista-and-newer friendly lock that allows concurrent reads from a resource that permits such
|
|
// Warning, non-recursion proof
|
|
class readWriteLock {
|
|
public:
|
|
readWriteLock() : theLock() {
|
|
}
|
|
|
|
void enterRead() {
|
|
AcquireSRWLockShared( & theLock );
|
|
}
|
|
void enterWrite() {
|
|
AcquireSRWLockExclusive( & theLock );
|
|
}
|
|
void leaveRead() {
|
|
ReleaseSRWLockShared( & theLock );
|
|
}
|
|
void leaveWrite() {
|
|
ReleaseSRWLockExclusive( &theLock );
|
|
}
|
|
|
|
private:
|
|
readWriteLock(const readWriteLock&) = delete;
|
|
void operator=(const readWriteLock&) = delete;
|
|
|
|
SRWLOCK theLock;
|
|
};
|
|
|
|
class _readWriteLock_scope_read {
|
|
public:
|
|
_readWriteLock_scope_read( readWriteLock & lock ) : m_lock( lock ) { m_lock.enterRead(); }
|
|
~_readWriteLock_scope_read() {m_lock.leaveRead();}
|
|
private:
|
|
_readWriteLock_scope_read( const _readWriteLock_scope_read &) = delete;
|
|
void operator=( const _readWriteLock_scope_read &) = delete;
|
|
readWriteLock & m_lock;
|
|
};
|
|
class _readWriteLock_scope_write {
|
|
public:
|
|
_readWriteLock_scope_write( readWriteLock & lock ) : m_lock( lock ) { m_lock.enterWrite(); }
|
|
~_readWriteLock_scope_write() {m_lock.leaveWrite();}
|
|
private:
|
|
_readWriteLock_scope_write( const _readWriteLock_scope_write &) = delete;
|
|
void operator=( const _readWriteLock_scope_write &) = delete;
|
|
readWriteLock & m_lock;
|
|
};
|
|
|
|
#define inReadSync( X ) ::pfc::_readWriteLock_scope_read _asdf_l_readWriteLock_scope_read( X )
|
|
#define inWriteSync( X ) ::pfc::_readWriteLock_scope_write _asdf_l_readWriteLock_scope_write( X )
|
|
|
|
typedef ::critical_section mutex;
|
|
typedef ::c_insync mutexScope;
|
|
|
|
}
|