mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-15 19:28:59 +00:00
Fix rare stream deadlock on Windows
This commit is contained in:
parent
b451be6c7f
commit
4368841f02
1 changed files with 27 additions and 14 deletions
|
@ -14,9 +14,9 @@ struct CdReadInfo
|
||||||
void *pBuffer;
|
void *pBuffer;
|
||||||
char field_C;
|
char field_C;
|
||||||
bool bLocked;
|
bool bLocked;
|
||||||
bool bInUse;
|
bool bReading;
|
||||||
int32 nStatus;
|
int32 nStatus;
|
||||||
HANDLE hSemaphore; // used for CdStreamSync
|
HANDLE pDoneSemaphore; // used for CdStreamSync
|
||||||
HANDLE hFile;
|
HANDLE hFile;
|
||||||
OVERLAPPED Overlapped;
|
OVERLAPPED Overlapped;
|
||||||
};
|
};
|
||||||
|
@ -53,9 +53,9 @@ CdStreamInitThread(void)
|
||||||
{
|
{
|
||||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||||
{
|
{
|
||||||
gpReadInfo[i].hSemaphore = CreateSemaphore(nil, 0, 2, nil);
|
gpReadInfo[i].pDoneSemaphore = CreateSemaphore(nil, 0, 2, nil);
|
||||||
|
|
||||||
if ( gpReadInfo[i].hSemaphore == nil )
|
if ( gpReadInfo[i].pDoneSemaphore == nil )
|
||||||
{
|
{
|
||||||
printf("%s: failed to create sync semaphore\n", "cdvd_stream");
|
printf("%s: failed to create sync semaphore\n", "cdvd_stream");
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
|
@ -183,7 +183,7 @@ CdStreamShutdown(void)
|
||||||
CloseHandle(_gCdStreamThread);
|
CloseHandle(_gCdStreamThread);
|
||||||
|
|
||||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||||
CloseHandle(gpReadInfo[i].hSemaphore);
|
CloseHandle(gpReadInfo[i].pDoneSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFree(gpReadInfo);
|
LocalFree(gpReadInfo);
|
||||||
|
@ -213,7 +213,7 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
||||||
|
|
||||||
if ( _gbCdStreamAsync )
|
if ( _gbCdStreamAsync )
|
||||||
{
|
{
|
||||||
if ( pChannel->nSectorsToRead != 0 || pChannel->bInUse )
|
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading )
|
||||||
return STREAM_NONE;
|
return STREAM_NONE;
|
||||||
|
|
||||||
pChannel->nStatus = STREAM_NONE;
|
pChannel->nStatus = STREAM_NONE;
|
||||||
|
@ -271,7 +271,7 @@ CdStreamGetStatus(int32 channel)
|
||||||
|
|
||||||
if ( _gbCdStreamAsync )
|
if ( _gbCdStreamAsync )
|
||||||
{
|
{
|
||||||
if ( pChannel->bInUse )
|
if ( pChannel->bReading )
|
||||||
return STREAM_READING;
|
return STREAM_READING;
|
||||||
|
|
||||||
if ( pChannel->nSectorsToRead != 0 )
|
if ( pChannel->nSectorsToRead != 0 )
|
||||||
|
@ -321,12 +321,21 @@ CdStreamSync(int32 channel)
|
||||||
{
|
{
|
||||||
pChannel->bLocked = true;
|
pChannel->bLocked = true;
|
||||||
|
|
||||||
ASSERT( pChannel->hSemaphore != nil );
|
ASSERT( pChannel->pDoneSemaphore != nil );
|
||||||
|
|
||||||
WaitForSingleObject(pChannel->hSemaphore, INFINITE);
|
// Deadlock fix 1
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
// This is while loop on Posix streamer, for spurious wakeups
|
||||||
|
if (pChannel->bLocked && pChannel->nSectorsToRead != 0){
|
||||||
|
WaitForSingleObject(pChannel->pDoneSemaphore, INFINITE);
|
||||||
|
}
|
||||||
|
pChannel->bLocked = false;
|
||||||
|
#else
|
||||||
|
WaitForSingleObject(pChannel->pDoneSemaphore, INFINITE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
pChannel->bInUse = false;
|
pChannel->bReading = false;
|
||||||
|
|
||||||
return pChannel->nStatus;
|
return pChannel->nStatus;
|
||||||
}
|
}
|
||||||
|
@ -398,7 +407,7 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
||||||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||||
ASSERT( pChannel != nil );
|
ASSERT( pChannel != nil );
|
||||||
|
|
||||||
pChannel->bInUse = true;
|
pChannel->bReading = true;
|
||||||
|
|
||||||
if ( pChannel->nStatus == STREAM_NONE )
|
if ( pChannel->nStatus == STREAM_NONE )
|
||||||
{
|
{
|
||||||
|
@ -455,11 +464,15 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
||||||
|
|
||||||
if ( pChannel->bLocked )
|
if ( pChannel->bLocked )
|
||||||
{
|
{
|
||||||
ASSERT( pChannel->hSemaphore != nil );
|
ASSERT( pChannel->pDoneSemaphore != nil );
|
||||||
ReleaseSemaphore(pChannel->hSemaphore, 1, NULL);
|
// Deadlock fix 2
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
pChannel->bLocked = 0;
|
||||||
|
#endif
|
||||||
|
ReleaseSemaphore(pChannel->pDoneSemaphore, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
pChannel->bInUse = false;
|
pChannel->bReading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue