mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 06:03:02 +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:
parent
397ceb7ed8
commit
ebc4644ea1
@ -93,16 +93,28 @@ public:
|
|||||||
explicit Mutex(MemoryPool&) {
|
explicit Mutex(MemoryPool&) {
|
||||||
InitializeCriticalSection(&spinlock);
|
InitializeCriticalSection(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Mutex() {
|
~Mutex() {
|
||||||
|
#ifdef DEV_BUILD
|
||||||
|
if (spinlock.OwningThread != 0)
|
||||||
|
DebugBreak();
|
||||||
|
#endif
|
||||||
DeleteCriticalSection(&spinlock);
|
DeleteCriticalSection(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enter() {
|
void enter() {
|
||||||
EnterCriticalSection(&spinlock);
|
EnterCriticalSection(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryEnter() {
|
bool tryEnter() {
|
||||||
return TryEnterCS::tryEnter(&spinlock);
|
return TryEnterCS::tryEnter(&spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void leave() {
|
void leave() {
|
||||||
|
#ifdef DEV_BUILD
|
||||||
|
if ((DWORD)spinlock.OwningThread != GetCurrentThreadId())
|
||||||
|
DebugBreak();
|
||||||
|
#endif
|
||||||
LeaveCriticalSection(&spinlock);
|
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
|
} //namespace Firebird
|
||||||
|
|
||||||
#endif // CLASSES_LOCKS_H
|
#endif // CLASSES_LOCKS_H
|
||||||
|
Loading…
Reference in New Issue
Block a user