1
0
Fork 0

Fix recursive deadlocks / some small bugs

This commit is contained in:
Nukem 2015-03-22 21:14:18 -04:00
parent b42bb8a19e
commit 4c115e5e7e
6 changed files with 85 additions and 64 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
*/

View File

@ -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;
};

View File

@ -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();

View File

@ -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)