Threads_Win32 fixes

From top to bottom,

- Fix incorrect gcc implementation in `SetThreadName`
- Static Cast in `StartThread`
- Fix `MutexImpl_Win32::Lock()`
- Remove unnecessary pre-winXP methods in PortableSignalObjectAndWait()
- Static Cast in `EventImpl_Win32::Wait`
This commit is contained in:
sukibaby
2024-08-06 15:31:24 -07:00
committed by teejusb
parent e2ae82deb2
commit 2fd1bff510
+21 -58
View File
@@ -75,28 +75,29 @@ typedef struct tagTHREADNAME_INFO
static void SetThreadName( DWORD dwThreadID, LPCTSTR szThreadName )
{
#if defined(_MSC_VER)
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
// FIXME: Need to find a GCC/GDB-friendly way to do this.
#if defined(_MSC_VER)
__try {
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR *)&info);
} __except (EXCEPTION_CONTINUE_EXECUTION) {
}
#elif defined(__GNUC__)
pthread_setname_np(pthread_self(), szThreadName);
#endif
}
static DWORD WINAPI StartThread( LPVOID pData )
{
ThreadImpl_Win32 *pThis = (ThreadImpl_Win32 *) pData;
ThreadImpl_Win32 *pThis = static_cast<ThreadImpl_Win32 *>(pData);
SetThreadName( GetCurrentThreadId(), RageThread::GetCurrentThreadName() );
DWORD ret = (DWORD) pThis->m_pFunc( pThis->m_pData );
DWORD ret = static_cast<DWORD>(pThis->m_pFunc(pThis->m_pData));
for( int i = 0; i < MAX_THREADS; ++i )
{
@@ -214,26 +215,24 @@ static bool SimpleWaitForSingleObject( HANDLE h, DWORD ms )
}
bool MutexImpl_Win32::Lock()
{
int len = 15000;
int tries = 5;
while( tries-- )
{
// Wait for fifteen seconds. If it takes longer than that, we're probably deadlocked.
if( SimpleWaitForSingleObject( mutex, len ) )
DWORD dwWaitResult = WaitForSingleObject(mutex, INFINITE);
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
return true;
case WAIT_TIMEOUT:
return false;
/* Timed out; probably deadlocked. Try a couple more times, with
* a smaller timeout, just in case we're debugging and happened
* to stop while waiting on the mutex. */
len = 1000;
case WAIT_ABANDONED:
return false;
default:
FAIL_M( "WaitForSingleObject failed in a way that shouldn't have been possible" );
}
}
return false;
}
bool MutexImpl_Win32::TryLock()
{
return SimpleWaitForSingleObject( mutex, 0 );
@@ -283,46 +282,8 @@ EventImpl_Win32::~EventImpl_Win32()
CloseHandle( m_WaitersDone );
}
/* SignalObjectAndWait is atomic, which leads to more fair event handling.
* However, we don't guarantee or depend upon fair events, and
* SignalObjectAndWait is only available in NT. I also can't find a single
* function to signal an object like SignalObjectAndWait, so we need to
* know if the object is a mutex or an event. */
static bool PortableSignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, bool bFirstParamIsMutex, unsigned iMilliseconds = INFINITE )
{
static bool bSignalObjectAndWaitUnavailable = false;
// Watch out: SignalObjectAndWait doesn't work when iMilliseconds is zero.
if( !bSignalObjectAndWaitUnavailable && iMilliseconds != 0 )
{
DWORD ret = SignalObjectAndWait( hObjectToSignal, hObjectToWaitOn, iMilliseconds, false );
switch( ret )
{
case WAIT_OBJECT_0:
return true;
case WAIT_ABANDONED:
// The docs aren't particular about what this does, but it should never happen.
FAIL_M( "WAIT_ABANDONED" );
case 1: // bogus Win98 return value
case WAIT_FAILED:
if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
{
// We're probably on 9x.
bSignalObjectAndWaitUnavailable = true;
break;
}
FAIL_M( werr_ssprintf(GetLastError(), "SignalObjectAndWait") );
case WAIT_TIMEOUT:
return false;
default:
FAIL_M( ssprintf("Unexpected code from SignalObjectAndWait: %d",ret ));
}
}
if( bFirstParamIsMutex )
{
const bool bRet = !!ReleaseMutex( hObjectToSignal );
@@ -330,7 +291,9 @@ static bool PortableSignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectT
sm_crash( werr_ssprintf( GetLastError(), "ReleaseMutex failed" ) );
}
else
{
SetEvent( hObjectToSignal );
}
DWORD ret = WaitForSingleObject( hObjectToWaitOn, iMilliseconds );
switch( ret )
@@ -361,7 +324,7 @@ bool EventImpl_Win32::Wait( RageTimer *pTimeout )
if( pTimeout != nullptr )
{
float fSecondsInFuture = -pTimeout->Ago();
iMilliseconds = (unsigned) std::max( 0, int( fSecondsInFuture * 1000 ) );
iMilliseconds = static_cast<unsigned>(std::max(0, static_cast<int>(fSecondsInFuture * 1000)));
}
// Unlock the mutex and wait for a signal.