mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-29 15:23:43 +00:00
Merge remote-tracking branch 'origin/miami' into lcs
* origin/miami: Fix FindClose->closedir Only include sys/syscall.h when __linux__ is defined Add unnamed semaphore define toggle for CdStreamPosix Fix rare stream deadlock on Windows
This commit is contained in:
commit
21278356ec
3 changed files with 97 additions and 33 deletions
|
@ -14,9 +14,9 @@ struct CdReadInfo
|
|||
void *pBuffer;
|
||||
char field_C;
|
||||
bool bLocked;
|
||||
bool bInUse;
|
||||
bool bReading;
|
||||
int32 nStatus;
|
||||
HANDLE hSemaphore; // used for CdStreamSync
|
||||
HANDLE pDoneSemaphore; // used for CdStreamSync
|
||||
HANDLE hFile;
|
||||
OVERLAPPED Overlapped;
|
||||
};
|
||||
|
@ -53,9 +53,9 @@ CdStreamInitThread(void)
|
|||
{
|
||||
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");
|
||||
ASSERT(0);
|
||||
|
@ -183,7 +183,7 @@ CdStreamShutdown(void)
|
|||
CloseHandle(_gCdStreamThread);
|
||||
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
CloseHandle(gpReadInfo[i].hSemaphore);
|
||||
CloseHandle(gpReadInfo[i].pDoneSemaphore);
|
||||
}
|
||||
|
||||
LocalFree(gpReadInfo);
|
||||
|
@ -213,7 +213,7 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
|
|||
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
if ( pChannel->nSectorsToRead != 0 || pChannel->bInUse )
|
||||
if ( pChannel->nSectorsToRead != 0 || pChannel->bReading )
|
||||
return STREAM_NONE;
|
||||
|
||||
pChannel->nStatus = STREAM_NONE;
|
||||
|
@ -271,7 +271,7 @@ CdStreamGetStatus(int32 channel)
|
|||
|
||||
if ( _gbCdStreamAsync )
|
||||
{
|
||||
if ( pChannel->bInUse )
|
||||
if ( pChannel->bReading )
|
||||
return STREAM_READING;
|
||||
|
||||
if ( pChannel->nSectorsToRead != 0 )
|
||||
|
@ -321,12 +321,21 @@ CdStreamSync(int32 channel)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -398,7 +407,7 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
|||
CdReadInfo *pChannel = &gpReadInfo[channel];
|
||||
ASSERT( pChannel != nil );
|
||||
|
||||
pChannel->bInUse = true;
|
||||
pChannel->bReading = true;
|
||||
|
||||
if ( pChannel->nStatus == STREAM_NONE )
|
||||
{
|
||||
|
@ -455,11 +464,15 @@ WINAPI CdStreamThread(LPVOID lpThreadParameter)
|
|||
|
||||
if ( pChannel->bLocked )
|
||||
{
|
||||
ASSERT( pChannel->hSemaphore != nil );
|
||||
ReleaseSemaphore(pChannel->hSemaphore, 1, NULL);
|
||||
ASSERT( pChannel->pDoneSemaphore != nil );
|
||||
// Deadlock fix 2
|
||||
#ifdef FIX_BUGS
|
||||
pChannel->bLocked = 0;
|
||||
#endif
|
||||
ReleaseSemaphore(pChannel->pDoneSemaphore, 1, NULL);
|
||||
}
|
||||
|
||||
pChannel->bInUse = false;
|
||||
pChannel->bReading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef _WIN32
|
||||
#include "common.h"
|
||||
#include "crossplatform.h"
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -12,7 +12,11 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#include "CdStream.h"
|
||||
#include "rwcore.h"
|
||||
|
@ -25,6 +29,58 @@
|
|||
bool flushStream[MAX_CDCHANNELS];
|
||||
#endif
|
||||
|
||||
#ifdef USE_UNNAMED_SEM
|
||||
|
||||
#define RE3_SEM_OPEN(name, ...) re3_sem_open()
|
||||
sem_t*
|
||||
re3_sem_open(void)
|
||||
{
|
||||
sem_t* sem = (sem_t*)malloc(sizeof(sem_t));
|
||||
if (sem_init(sem, 0, 1) == -1) {
|
||||
sem = SEM_FAILED;
|
||||
}
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
#define RE3_SEM_CLOSE(sem, format, ...) re3_sem_close(sem)
|
||||
void
|
||||
re3_sem_close(sem_t* sem)
|
||||
{
|
||||
sem_destroy(sem);
|
||||
free(sem);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define RE3_SEM_OPEN re3_sem_open
|
||||
sem_t*
|
||||
re3_sem_open(const char* format, ...)
|
||||
{
|
||||
char semName[20];
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsprintf(semName, format, va);
|
||||
|
||||
return sem_open(semName, O_CREAT, 0644, 1);
|
||||
}
|
||||
|
||||
#define RE3_SEM_CLOSE re3_sem_close
|
||||
void
|
||||
re3_sem_close(sem_t* sem, const char* format, ...)
|
||||
{
|
||||
sem_close(sem);
|
||||
|
||||
char semName[20];
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsprintf(semName, format, va);
|
||||
|
||||
sem_unlink(semName);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct CdReadInfo
|
||||
{
|
||||
uint32 nSectorOffset;
|
||||
|
@ -69,14 +125,13 @@ void
|
|||
CdStreamInitThread(void)
|
||||
{
|
||||
int status;
|
||||
char semName[20];
|
||||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
gChannelRequestQ.items = (int32 *)calloc(gNumChannels + 1, sizeof(int32));
|
||||
gChannelRequestQ.head = 0;
|
||||
gChannelRequestQ.tail = 0;
|
||||
gChannelRequestQ.size = gNumChannels + 1;
|
||||
ASSERT(gChannelRequestQ.items != nil );
|
||||
gCdStreamSema = sem_open("/semaphore_cd_stream", O_CREAT, 0644, 0);
|
||||
gCdStreamSema = RE3_SEM_OPEN("/semaphore_cd_stream");
|
||||
|
||||
|
||||
if (gCdStreamSema == SEM_FAILED) {
|
||||
|
@ -90,8 +145,7 @@ CdStreamInitThread(void)
|
|||
{
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
{
|
||||
sprintf(semName,"/semaphore_done%d",i);
|
||||
gpReadInfo[i].pDoneSemaphore = sem_open(semName, O_CREAT, 0644, 0);
|
||||
gpReadInfo[i].pDoneSemaphore = RE3_SEM_OPEN("/semaphore_done%d", i);
|
||||
|
||||
if (gpReadInfo[i].pDoneSemaphore == SEM_FAILED)
|
||||
{
|
||||
|
@ -101,8 +155,7 @@ CdStreamInitThread(void)
|
|||
}
|
||||
|
||||
#ifdef ONE_THREAD_PER_CHANNEL
|
||||
sprintf(semName,"/semaphore_start%d",i);
|
||||
gpReadInfo[i].pStartSemaphore = sem_open(semName, O_CREAT, 0644, 0);
|
||||
gpReadInfo[i].pStartSemaphore = RE3_SEM_OPEN("/semaphore_start%d", i);
|
||||
|
||||
if (gpReadInfo[i].pStartSemaphore == SEM_FAILED)
|
||||
{
|
||||
|
@ -464,21 +517,14 @@ void *CdStreamThread(void *param)
|
|||
#ifndef ONE_THREAD_PER_CHANNEL
|
||||
for ( int32 i = 0; i < gNumChannels; i++ )
|
||||
{
|
||||
sem_close(gpReadInfo[i].pDoneSemaphore);
|
||||
sprintf(semName,"/semaphore_done%d",i);
|
||||
sem_unlink(semName);
|
||||
RE3_SEM_CLOSE(gpReadInfo[i].pDoneSemaphore, "/semaphore_done%d", i);
|
||||
}
|
||||
sem_close(gCdStreamSema);
|
||||
sem_unlink("/semaphore_cd_stream");
|
||||
RE3_SEM_CLOSE(gCdStreamSema, "/semaphore_cd_stream");
|
||||
free(gChannelRequestQ.items);
|
||||
#else
|
||||
sem_close(gpReadInfo[channel].pStartSemaphore);
|
||||
sprintf(semName,"/semaphore_start%d",channel);
|
||||
sem_unlink(semName);
|
||||
RE3_SEM_CLOSE(gpReadInfo[channel].pStartSemaphore, "/semaphore_start%d", channel);
|
||||
|
||||
sem_close(gpReadInfo[channel].pDoneSemaphore);
|
||||
sprintf(semName,"/semaphore_done%d",channel);
|
||||
sem_unlink(semName);
|
||||
RE3_SEM_CLOSE(gpReadInfo[channel].pDoneSemaphore, "/semaphore_done%d", channel);
|
||||
#endif
|
||||
if (gpReadInfo)
|
||||
free(gpReadInfo);
|
||||
|
|
|
@ -136,7 +136,12 @@ void GetLocalTime_CP(SYSTEMTIME* out);
|
|||
|
||||
typedef void* HANDLE;
|
||||
#define INVALID_HANDLE_VALUE NULL
|
||||
#define FindClose(h) closedir((DIR*)h)
|
||||
#define FindClose(h) \
|
||||
do { \
|
||||
if (h != nil) \
|
||||
closedir((DIR*)h); \
|
||||
} while(0)
|
||||
|
||||
#define LOCALE_USER_DEFAULT 0
|
||||
#define DATE_SHORTDATE 0
|
||||
|
||||
|
|
Loading…
Reference in a new issue