1
0
Fork 0
x64dbg/x64_dbg_dbg/threading.h

154 lines
3.8 KiB
C++

#pragma once
#include "_global.h"
enum WAIT_ID
{
WAITID_RUN,
WAITID_STOP,
WAITID_LAST
};
//functions
void waitclear();
void wait(WAIT_ID id);
void lock(WAIT_ID id);
void unlock(WAIT_ID id);
bool waitislocked(WAIT_ID id);
void waitinitialize();
void waitdeinitialize();
//
// THREAD SYNCHRONIZATION
//
// Better, but requires VISTA+
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx
//
#define EXCLUSIVE_ACQUIRE(Index) SectionLocker<SectionLock::##Index, false> __ThreadLock;
#define EXCLUSIVE_REACQUIRE() __ThreadLock.Lock();
#define EXCLUSIVE_RELEASE() __ThreadLock.Unlock();
#define SHARED_ACQUIRE(Index) SectionLocker<SectionLock::##Index, true> __SThreadLock;
#define SHARED_REACQUIRE() __SThreadLock.Lock();
#define SHARED_RELEASE() __SThreadLock.Unlock();
enum SectionLock
{
LockMemoryPages,
LockVariables,
LockModules,
LockComments,
LockLabels,
LockBookmarks,
LockFunctions,
LockLoops,
LockBreakpoints,
LockPatches,
LockThreads,
LockDprintf,
LockSym,
// This is defined because of a bug in the Windows 8.1 kernel;
// Calling VirtualQuery/VirtualProtect/ReadProcessMemory can and will cause
// a deadlock.
// https://bitbucket.org/mrexodia/x64_dbg/issue/247/x64-dbg-bug-string-references-function
LockWin8Workaround,
LockPluginList,
LockPluginCallbackList,
LockPluginCommandList,
LockPluginMenuList,
LockLast,
};
class SectionLockerGlobal
{
template<SectionLock LockIndex, bool Shared> friend class SectionLocker;
public:
static void Initialize();
static void Deinitialize();
static inline void AcquireLock(SectionLock LockIndex, bool Shared)
{
Initialize(); // Locks can be accessed before we know when to initialize
if(m_SRWLocks)
{
if(Shared)
m_AcquireSRWLockShared(&m_srwLocks[LockIndex]);
else
m_AcquireSRWLockExclusive(&m_srwLocks[LockIndex]);
}
else
EnterCriticalSection(&m_crLocks[LockIndex]);
}
static inline void ReleaseLock(SectionLock LockIndex, bool Shared)
{
if(m_SRWLocks)
{
if(Shared)
m_ReleaseSRWLockShared(&m_srwLocks[LockIndex]);
else
m_ReleaseSRWLockExclusive(&m_srwLocks[LockIndex]);
}
else
LeaveCriticalSection(&m_crLocks[LockIndex]);
}
private:
typedef void (WINAPI* SRWLOCKFUNCTION)(PSRWLOCK SWRLock);
static bool m_Initialized;
static bool m_SRWLocks;
static SRWLOCK m_srwLocks[SectionLock::LockLast];
static CRITICAL_SECTION m_crLocks[SectionLock::LockLast];
static SRWLOCKFUNCTION m_InitializeSRWLock;
static SRWLOCKFUNCTION m_AcquireSRWLockShared;
static SRWLOCKFUNCTION m_AcquireSRWLockExclusive;
static SRWLOCKFUNCTION m_ReleaseSRWLockShared;
static SRWLOCKFUNCTION m_ReleaseSRWLockExclusive;
};
template<SectionLock LockIndex, bool Shared>
class SectionLocker
{
public:
SectionLocker()
{
m_LockCount = 0;
Lock();
}
~SectionLocker()
{
if(m_LockCount > 0)
Unlock();
#ifdef _DEBUG
// TODO: Assert that the lock count is zero on destructor
if(m_LockCount > 0)
__debugbreak();
#endif
}
inline void Lock()
{
Internal::AcquireLock(LockIndex, Shared);
m_LockCount++;
}
inline void Unlock()
{
m_LockCount--;
Internal::ReleaseLock(LockIndex, Shared);
}
private:
using Internal = SectionLockerGlobal;
protected:
BYTE m_LockCount;
};