mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
CdStreamSync fix: Use a RAII wrapper for cdstream critical section
This commit is contained in:
parent
db745b974a
commit
8d9ba3a97a
1 changed files with 40 additions and 12 deletions
|
@ -1049,6 +1049,38 @@ namespace CdStreamSync {
|
||||||
|
|
||||||
static CRITICAL_SECTION CdStreamCritSec;
|
static CRITICAL_SECTION CdStreamCritSec;
|
||||||
|
|
||||||
|
// WRL-like lock object
|
||||||
|
// Balancing lock/unlock is up to the user!
|
||||||
|
class SyncLock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SyncLock( CRITICAL_SECTION& critSec )
|
||||||
|
: m_critSec( critSec )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
~SyncLock()
|
||||||
|
{
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lock() const { EnterCriticalSection( &m_critSec ); }
|
||||||
|
void Unlock() const { LeaveCriticalSection( &m_critSec ); }
|
||||||
|
|
||||||
|
CRITICAL_SECTION* Get() const { return &m_critSec; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SyncLock( const SyncLock& ) = delete;
|
||||||
|
SyncLock( SyncLock&& ) = delete;
|
||||||
|
SyncLock& operator=( const SyncLock& ) = delete;
|
||||||
|
SyncLock& operator=( SyncLock&& ) = delete;
|
||||||
|
|
||||||
|
CRITICAL_SECTION& m_critSec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function pointers for game to use
|
// Function pointers for game to use
|
||||||
static CdStream::Sync (__stdcall *CdStreamInitializeSyncObject)();
|
static CdStream::Sync (__stdcall *CdStreamInitializeSyncObject)();
|
||||||
static DWORD (__stdcall *CdStreamSyncOnObject)( CdStream* stream );
|
static DWORD (__stdcall *CdStreamSyncOnObject)( CdStream* stream );
|
||||||
|
@ -1085,29 +1117,27 @@ namespace Sema
|
||||||
|
|
||||||
DWORD __stdcall CdStreamSync( CdStream* stream )
|
DWORD __stdcall CdStreamSync( CdStream* stream )
|
||||||
{
|
{
|
||||||
EnterCriticalSection( &CdStreamCritSec );
|
auto lock = SyncLock( CdStreamCritSec );
|
||||||
if ( stream->nSectorsToRead != 0 )
|
if ( stream->nSectorsToRead != 0 )
|
||||||
{
|
{
|
||||||
stream->bLocked = 1;
|
stream->bLocked = 1;
|
||||||
LeaveCriticalSection( &CdStreamCritSec );
|
lock.Unlock();
|
||||||
WaitForSingleObject( stream->sync.semaphore, INFINITE );
|
WaitForSingleObject( stream->sync.semaphore, INFINITE );
|
||||||
EnterCriticalSection( &CdStreamCritSec );
|
lock.Lock();
|
||||||
}
|
}
|
||||||
stream->bInUse = 0;
|
stream->bInUse = 0;
|
||||||
LeaveCriticalSection( &CdStreamCritSec );
|
|
||||||
return stream->status;
|
return stream->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall CdStreamThread( CdStream* stream )
|
void __stdcall CdStreamThread( CdStream* stream )
|
||||||
{
|
{
|
||||||
EnterCriticalSection( &CdStreamCritSec );
|
auto lock = SyncLock( CdStreamCritSec );
|
||||||
stream->nSectorsToRead = 0;
|
stream->nSectorsToRead = 0;
|
||||||
if ( stream->bLocked != 0 )
|
if ( stream->bLocked != 0 )
|
||||||
{
|
{
|
||||||
ReleaseSemaphore( stream->sync.semaphore, 1, nullptr );
|
ReleaseSemaphore( stream->sync.semaphore, 1, nullptr );
|
||||||
}
|
}
|
||||||
stream->bInUse = 0;
|
stream->bInUse = 0;
|
||||||
LeaveCriticalSection( &CdStreamCritSec );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,23 +1176,21 @@ namespace CV
|
||||||
|
|
||||||
DWORD __stdcall CdStreamSync( CdStream* stream )
|
DWORD __stdcall CdStreamSync( CdStream* stream )
|
||||||
{
|
{
|
||||||
EnterCriticalSection( &CdStreamCritSec );
|
auto lock = SyncLock( CdStreamCritSec );
|
||||||
while ( stream->nSectorsToRead != 0 )
|
while ( stream->nSectorsToRead != 0 )
|
||||||
{
|
{
|
||||||
Funcs::pSleepConditionVariableCS( &stream->sync.cv, &CdStreamCritSec, INFINITE );
|
Funcs::pSleepConditionVariableCS( &stream->sync.cv, lock.Get(), INFINITE );
|
||||||
}
|
}
|
||||||
stream->bInUse = 0;
|
stream->bInUse = 0;
|
||||||
LeaveCriticalSection( &CdStreamCritSec );
|
|
||||||
return stream->status;
|
return stream->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall CdStreamThread( CdStream* stream )
|
void __stdcall CdStreamThread( CdStream* stream )
|
||||||
{
|
{
|
||||||
EnterCriticalSection( &CdStreamCritSec );
|
auto lock = SyncLock( CdStreamCritSec );
|
||||||
stream->nSectorsToRead = 0;
|
stream->nSectorsToRead = 0;
|
||||||
Funcs::pWakeConditionVariable( &stream->sync.cv );
|
Funcs::pWakeConditionVariable( &stream->sync.cv );
|
||||||
stream->bInUse = 0;
|
stream->bInUse = 0;
|
||||||
LeaveCriticalSection( &CdStreamCritSec );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1212,7 @@ static void CdStreamInitThread()
|
||||||
CdStreamThreadOnObject = Sema::CdStreamThread;
|
CdStreamThreadOnObject = Sema::CdStreamThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeCriticalSectionAndSpinCount( &CdStreamCritSec, 10 );
|
InitializeCriticalSection( &CdStreamCritSec );
|
||||||
|
|
||||||
FLAUtils::SetCdStreamWakeFunction( []( CdStream* pStream ) {
|
FLAUtils::SetCdStreamWakeFunction( []( CdStream* pStream ) {
|
||||||
CdStreamThreadOnObject( pStream );
|
CdStreamThreadOnObject( pStream );
|
||||||
|
|
Loading…
Reference in a new issue