Add R/W lock to OS-specific wrapper

This commit is contained in:
baldurk
2018-06-13 09:17:03 +01:00
parent ea3e2c8610
commit de969105d4
6 changed files with 138 additions and 15 deletions
+16 -11
View File
@@ -38,21 +38,26 @@ private:
CriticalSection *m_CS;
};
class TryScopedLock
class ScopedReadLock
{
public:
TryScopedLock(CriticalSection &cs) : m_CS(&cs) { m_Owned = m_CS->Trylock(); }
~TryScopedLock()
{
if(m_Owned)
m_CS->Unlock();
}
bool HasLock() const { return m_Owned; }
ScopedReadLock(RWLock &rw) : m_RW(&rw) { m_RW->ReadLock(); }
~ScopedReadLock() { m_RW->ReadUnlock(); }
private:
CriticalSection *m_CS;
bool m_Owned;
RWLock *m_RW;
};
class ScopedWriteLock
{
public:
ScopedWriteLock(RWLock &rw) : m_RW(&rw) { m_RW->WriteLock(); }
~ScopedWriteLock() { m_RW->WriteUnlock(); }
private:
RWLock *m_RW;
};
};
#define SCOPED_LOCK(cs) Threading::ScopedLock CONCAT(scopedlock, __LINE__)(cs);
#define SCOPED_READLOCK(rw) Threading::ScopedReadLock CONCAT(scopedlock, __LINE__)(rw);
#define SCOPED_WRITELOCK(rw) Threading::ScopedWriteLock CONCAT(scopedlock, __LINE__)(rw);
+24 -3
View File
@@ -99,10 +99,31 @@ public:
bool Trylock();
void Unlock();
private:
// no copying
CriticalSectionTemplate &operator=(const CriticalSectionTemplate &other);
CriticalSectionTemplate(const CriticalSectionTemplate &other);
CriticalSectionTemplate &operator=(const CriticalSectionTemplate &other) = delete;
CriticalSectionTemplate(const CriticalSectionTemplate &other) = delete;
data m_Data;
};
template <class data>
class RWLockTemplate
{
public:
RWLockTemplate();
~RWLockTemplate();
void ReadLock();
bool TryReadlock();
void ReadUnlock();
void WriteLock();
bool TryWritelock();
void WriteUnlock();
// no copying
RWLockTemplate &operator=(const RWLockTemplate &other) = delete;
RWLockTemplate(const RWLockTemplate &other) = delete;
data m_Data;
};
+7
View File
@@ -83,6 +83,13 @@ struct pthreadLockData
pthread_mutexattr_t attr;
};
typedef CriticalSectionTemplate<pthreadLockData> CriticalSection;
struct pthreadRWLockData
{
pthread_rwlock_t rwlock;
pthread_rwlockattr_t attr;
};
typedef RWLockTemplate<pthreadRWLockData> RWLock;
};
namespace Bits
+50
View File
@@ -101,6 +101,56 @@ void CriticalSection::Unlock()
pthread_mutex_unlock(&m_Data.lock);
}
template <>
RWLock::RWLockTemplate()
{
pthread_rwlockattr_init(&m_Data.attr);
pthread_rwlock_init(&m_Data.rwlock, &m_Data.attr);
}
template <>
RWLock::~RWLockTemplate()
{
pthread_rwlock_destroy(&m_Data.rwlock);
pthread_rwlockattr_destroy(&m_Data.attr);
}
template <>
void RWLock::WriteLock()
{
pthread_rwlock_wrlock(&m_Data.rwlock);
}
template <>
bool RWLock::TryWritelock()
{
return pthread_rwlock_trywrlock(&m_Data.rwlock) == 0;
}
template <>
void RWLock::WriteUnlock()
{
pthread_rwlock_unlock(&m_Data.rwlock);
}
template <>
void RWLock::ReadLock()
{
pthread_rwlock_rdlock(&m_Data.rwlock);
}
template <>
bool RWLock::TryReadlock()
{
return pthread_rwlock_tryrdlock(&m_Data.rwlock) == 0;
}
template <>
void RWLock::ReadUnlock()
{
pthread_rwlock_unlock(&m_Data.rwlock);
}
struct ThreadInitData
{
std::function<void()> entryFunc;
+1
View File
@@ -73,6 +73,7 @@ void WriteOutput(int channel, const char *str);
namespace Threading
{
typedef CriticalSectionTemplate<CRITICAL_SECTION> CriticalSection;
typedef RWLockTemplate<SRWLOCK> RWLock;
};
namespace Bits
+40 -1
View File
@@ -98,7 +98,7 @@ void CriticalSection::Lock()
bool CriticalSection::Trylock()
{
return TryEnterCriticalSection(&m_Data) == TRUE;
return TryEnterCriticalSection(&m_Data) != FALSE;
}
void CriticalSection::Unlock()
@@ -106,6 +106,45 @@ void CriticalSection::Unlock()
LeaveCriticalSection(&m_Data);
}
RWLock::RWLockTemplate()
{
InitializeSRWLock(&m_Data);
}
RWLock::~RWLockTemplate()
{
}
void RWLock::WriteLock()
{
AcquireSRWLockExclusive(&m_Data);
}
bool RWLock::TryWritelock()
{
return TryAcquireSRWLockExclusive(&m_Data) != FALSE;
}
void RWLock::WriteUnlock()
{
ReleaseSRWLockExclusive(&m_Data);
}
void RWLock::ReadLock()
{
AcquireSRWLockShared(&m_Data);
}
bool RWLock::TryReadlock()
{
return TryAcquireSRWLockShared(&m_Data) != FALSE;
}
void RWLock::ReadUnlock()
{
ReleaseSRWLockShared(&m_Data);
}
struct ThreadInitData
{
std::function<void()> entryFunc;