154 lines
3.8 KiB
C++
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;
|
|
}; |