8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 03:23:04 +01:00

Add check in WIN_NT's DEV_BUILD for correct mutex unlocking\deleting.

Implement new EnsureUnlock class for use instead of (or together with) LockGuard's if LockGuard is not usable.
This commit is contained in:
hvlad 2008-03-13 12:54:31 +00:00
parent 397ceb7ed8
commit ebc4644ea1

View File

@ -93,16 +93,28 @@ public:
explicit Mutex(MemoryPool&) {
InitializeCriticalSection(&spinlock);
}
~Mutex() {
#ifdef DEV_BUILD
if (spinlock.OwningThread != 0)
DebugBreak();
#endif
DeleteCriticalSection(&spinlock);
}
void enter() {
EnterCriticalSection(&spinlock);
}
bool tryEnter() {
return TryEnterCS::tryEnter(&spinlock);
}
void leave() {
#ifdef DEV_BUILD
if ((DWORD)spinlock.OwningThread != GetCurrentThreadId())
DebugBreak();
#endif
LeaveCriticalSection(&spinlock);
}
@ -368,6 +380,81 @@ private:
};
template <typename T>
class DefaultRefCounted
{
public:
static int addRef(T *object) {
return object->addRef();
}
static int release(T *object) {
return object->release();
}
};
template <typename T>
class NotRefCounted
{
public:
static int addRef(void*) {
return 0;
}
static int release(void*) {
return 0;
}
};
template <typename Mtx, typename RefCounted = DefaultRefCounted<Mtx> >
class EnsureUnlock
{
public:
explicit EnsureUnlock(Mtx &mutex)
{
m_mutex = &mutex;
RefCounted::addRef(m_mutex);
m_locked = 0;
}
~EnsureUnlock()
{
while (m_locked)
leave();
RefCounted::release(m_mutex);
}
void enter()
{
m_mutex->enter();
m_locked++;
}
bool tryEnter()
{
if (m_mutex->tryEnter())
{
m_locked++;
return true;
}
return false;
}
void leave()
{
m_mutex->leave();
m_locked--;
}
private:
Mtx *m_mutex;
int m_locked;
};
typedef EnsureUnlock<Mutex, NotRefCounted<Mutex> > MutexEnsureUnlock;
typedef EnsureUnlock<RefMutex> RefMutexEnsureUnlock;
} //namespace Firebird
#endif // CLASSES_LOCKS_H