Fix recursive deadlocks / some small bugs
This commit is contained in:
parent
b42bb8a19e
commit
4c115e5e7e
|
@ -68,7 +68,7 @@ void dbload()
|
|||
return;
|
||||
}
|
||||
FILE* jsonFile = 0;
|
||||
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"rb"))
|
||||
if(_wfopen_s(&jsonFile, wdbpath.c_str(), L"rb") != 0)
|
||||
{
|
||||
dputs("\nfailed to open database file!");
|
||||
return;
|
||||
|
|
|
@ -33,8 +33,8 @@ bool ModLoad(uint Base, uint Size, const char* FullPath)
|
|||
|
||||
if(extensionPos)
|
||||
{
|
||||
strcpy_s(info.extension, extensionPos);
|
||||
extensionPos[0] = '\0';
|
||||
strcpy_s(info.extension, extensionPos + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,7 @@ bool ModUnload(uint Base)
|
|||
|
||||
// Unload everything from TitanEngine
|
||||
StaticFileUnloadW(nullptr, false, found->second.Handle, found->second.FileMapSize, found->second.MapHandle, found->second.FileMapVA);
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
// Update symbols
|
||||
SymUpdateModuleList();
|
||||
|
|
|
@ -28,10 +28,10 @@ bool waitislocked(WAIT_ID id)
|
|||
return waitarray[id];
|
||||
}
|
||||
|
||||
bool ExclusiveSectionLocker::m_Initialized = false;
|
||||
SRWLOCK ExclusiveSectionLocker::m_Locks[SectionLock::LockLast];
|
||||
bool SectionLockerGlobal::m_Initialized = false;
|
||||
SRWLOCK SectionLockerGlobal::m_Locks[SectionLock::LockLast];
|
||||
|
||||
void ExclusiveSectionLocker::Initialize()
|
||||
void SectionLockerGlobal::Initialize()
|
||||
{
|
||||
if(m_Initialized)
|
||||
return;
|
||||
|
@ -45,7 +45,7 @@ void ExclusiveSectionLocker::Initialize()
|
|||
m_Initialized = true;
|
||||
}
|
||||
|
||||
void ExclusiveSectionLocker::Deinitialize()
|
||||
void SectionLockerGlobal::Deinitialize()
|
||||
{
|
||||
if(!m_Initialized)
|
||||
return;
|
||||
|
@ -63,38 +63,7 @@ void ExclusiveSectionLocker::Deinitialize()
|
|||
m_Initialized = false;
|
||||
}
|
||||
|
||||
ExclusiveSectionLocker::ExclusiveSectionLocker(SectionLock LockIndex)
|
||||
{
|
||||
m_Lock = &m_Locks[LockIndex];
|
||||
m_LockCount = 0;
|
||||
|
||||
Lock();
|
||||
}
|
||||
|
||||
ExclusiveSectionLocker::~ExclusiveSectionLocker()
|
||||
{
|
||||
if(m_LockCount > 0)
|
||||
Unlock();
|
||||
|
||||
// TODO: Assert that the lock count is zero on destructor
|
||||
#ifdef _DEBUG
|
||||
if(m_LockCount > 0)
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ExclusiveSectionLocker::Lock()
|
||||
{
|
||||
AcquireSRWLockExclusive(m_Lock);
|
||||
m_LockCount++;
|
||||
}
|
||||
|
||||
void ExclusiveSectionLocker::Unlock()
|
||||
{
|
||||
m_LockCount--;
|
||||
ReleaseSRWLockExclusive(m_Lock);
|
||||
}
|
||||
|
||||
/*
|
||||
SharedSectionLocker::SharedSectionLocker(SectionLock LockIndex)
|
||||
: ExclusiveSectionLocker(LockIndex)
|
||||
{
|
||||
|
@ -111,4 +80,5 @@ void SharedSectionLocker::Unlock()
|
|||
{
|
||||
m_LockCount--;
|
||||
ReleaseSRWLockShared(m_Lock);
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "_global.h"
|
||||
|
||||
//enums
|
||||
enum WAIT_ID
|
||||
{
|
||||
WAITID_RUN,
|
||||
|
@ -23,10 +22,13 @@ bool waitislocked(WAIT_ID id);
|
|||
// Better, but requires VISTA+
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx
|
||||
//
|
||||
#define EXCLUSIVE_ACQUIRE(Index) ExclusiveSectionLocker __ThreadLock(SectionLock::##Index);
|
||||
#define CriticalSectionLocker
|
||||
#define locker(x) EXCLUSIVE_ACQUIRE(x)
|
||||
|
||||
#define EXCLUSIVE_ACQUIRE(Index) SectionLocker<false> __ThreadLock(SectionLock::##Index);
|
||||
#define EXCLUSIVE_RELEASE() __ThreadLock.Unlock();
|
||||
|
||||
#define SHARED_ACQUIRE(Index) SharedSectionLocker __SThreadLock(SectionLock::##Index);
|
||||
#define SHARED_ACQUIRE(Index) SectionLocker<true> __SThreadLock(SectionLock::##Index);
|
||||
#define SHARED_RELEASE() __SThreadLock.Unlock();
|
||||
|
||||
enum SectionLock
|
||||
|
@ -53,32 +55,56 @@ enum SectionLock
|
|||
LockLast
|
||||
};
|
||||
|
||||
class ExclusiveSectionLocker
|
||||
class SectionLockerGlobal
|
||||
{
|
||||
template<bool Shared> friend class SectionLocker;
|
||||
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Deinitialize();
|
||||
|
||||
ExclusiveSectionLocker(SectionLock LockIndex);
|
||||
~ExclusiveSectionLocker();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
protected:
|
||||
static bool m_Initialized;
|
||||
static SRWLOCK m_Locks[SectionLock::LockLast];
|
||||
|
||||
protected:
|
||||
SRWLOCK* m_Lock;
|
||||
BYTE m_LockCount;
|
||||
};
|
||||
|
||||
class SharedSectionLocker : public ExclusiveSectionLocker
|
||||
template<bool Shared>
|
||||
class SectionLocker
|
||||
{
|
||||
public:
|
||||
SharedSectionLocker(SectionLock LockIndex);
|
||||
SectionLocker(SectionLock LockIndex)
|
||||
{
|
||||
m_Lock = &SectionLockerGlobal::m_Locks[LockIndex];
|
||||
m_LockCount = 0;
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
Lock();
|
||||
}
|
||||
|
||||
~SectionLocker()
|
||||
{
|
||||
if(m_LockCount > 0)
|
||||
Unlock();
|
||||
|
||||
// TODO: Assert that the lock count is zero on destructor
|
||||
#ifdef _DEBUG
|
||||
if(m_LockCount > 0)
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void Lock()
|
||||
{
|
||||
AcquireSRWLockExclusive(m_Lock);
|
||||
m_LockCount++;
|
||||
}
|
||||
|
||||
inline void Unlock()
|
||||
{
|
||||
m_LockCount--;
|
||||
ReleaseSRWLockExclusive(m_Lock);
|
||||
}
|
||||
|
||||
protected:
|
||||
PSRWLOCK m_Lock;
|
||||
BYTE m_LockCount;
|
||||
};
|
|
@ -20,16 +20,23 @@ static void varsetvalue(VAR* var, VAR_VALUE* value)
|
|||
|
||||
static bool varset(const char* name, VAR_VALUE* value, bool setreadonly)
|
||||
{
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
name_ += name;
|
||||
VariableMap::iterator found = variables.find(name_);
|
||||
if(found == variables.end()) //not found
|
||||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
return varset(found->second.alias.c_str(), value, setreadonly);
|
||||
}
|
||||
|
||||
if(!setreadonly && (found->second.type == VAR_READONLY || found->second.type == VAR_HIDDEN))
|
||||
return false;
|
||||
varsetvalue(&found->second, value);
|
||||
|
@ -69,9 +76,11 @@ VAR* vargetptr()
|
|||
|
||||
bool varnew(const char* name, uint value, VAR_TYPE type)
|
||||
{
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
if(!name)
|
||||
return false;
|
||||
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
|
||||
std::vector<String> names = StringUtils::Split(name, '\1');
|
||||
String firstName;
|
||||
for(int i = 0; i < (int)names.size(); i++)
|
||||
|
@ -100,7 +109,8 @@ bool varnew(const char* name, uint value, VAR_TYPE type)
|
|||
|
||||
static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type)
|
||||
{
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
|
@ -109,7 +119,12 @@ static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type
|
|||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
return varget(found->second.alias.c_str(), value, size, type);
|
||||
}
|
||||
if(type)
|
||||
*type = found->second.type;
|
||||
if(size)
|
||||
|
@ -184,7 +199,8 @@ bool varset(const char* name, const char* string, bool setreadonly)
|
|||
|
||||
bool vardel(const char* name, bool delsystem)
|
||||
{
|
||||
CriticalSectionLocker locker(LockVariables);
|
||||
EXCLUSIVE_ACQUIRE(LockVariables);
|
||||
|
||||
String name_;
|
||||
if(*name != '$')
|
||||
name_ = "$";
|
||||
|
@ -193,7 +209,13 @@ bool vardel(const char* name, bool delsystem)
|
|||
if(found == variables.end()) //not found
|
||||
return false;
|
||||
if(found->second.alias.length())
|
||||
{
|
||||
// Release the lock (potential deadlock here)
|
||||
EXCLUSIVE_RELEASE();
|
||||
|
||||
return vardel(found->second.alias.c_str(), delsystem);
|
||||
}
|
||||
|
||||
if(!delsystem && found->second.type != VAR_USER)
|
||||
return false;
|
||||
found = variables.begin();
|
||||
|
|
|
@ -236,6 +236,7 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
return "Invalid TITAN_ENGINE_CONTEXT_t alignment!";
|
||||
if(sizeof(TITAN_ENGINE_CONTEXT_t) != sizeof(REGISTERCONTEXT))
|
||||
return "Invalid REGISTERCONTEXT alignment!";
|
||||
SectionLockerGlobal::Initialize();
|
||||
dbginit();
|
||||
dbgfunctionsinit();
|
||||
json_set_alloc_funcs(emalloc_json, efree_json);
|
||||
|
@ -314,7 +315,8 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
}
|
||||
else
|
||||
DeleteFileA(alloctrace);
|
||||
CriticalSectionLocker::Deinitialize();
|
||||
|
||||
SectionLockerGlobal::Deinitialize();
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd)
|
||||
|
|
Loading…
Reference in New Issue