diff --git a/engine/common/common.c b/engine/common/common.c index 37bf2c34d..7c880cbc9 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -6215,6 +6215,22 @@ static void COM_InitWorkerThread(void) Cvar_Register(&worker_sleeptime, NULL); Cvar_ForceCallback(&worker_count); } + +qint32_t FTE_Atomic32Mutex_Add(qint32_t *ptr, qint32_t change) +{ + qint32_t r; + Sys_LockMutex(com_resourcemutex); + r = (*ptr += change); + Sys_UnlockMutex(com_resourcemutex); + return r; +} +#else +qint32_t FTE_Atomic32Mutex_Add(qint32_t *ptr, qint32_t change) +{ + qint32_t r; + r = (*ptr += change); + return r; +} #endif /* diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index a3e139daa..6817c2adf 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -25,7 +25,7 @@ typedef struct pack_s void *mutex; vfsfile_t *handle; unsigned int filepos; //the pos the subfiles left it at (to optimize calls to vfs_seek) - int references; //seeing as all vfiles from a pak file use the parent's vfsfile, we need to keep the parent open until all subfiles are closed. + qatomic32_t references; //seeing as all vfiles from a pak file use the parent's vfsfile, we need to keep the parent open until all subfiles are closed. } pack_t; // @@ -67,15 +67,17 @@ static void QDECL FSPAK_GetPathDetails(searchpathfuncs_t *handle, char *out, siz if (pak->references != 1) Q_snprintfz(out, outlen, "(%i)", pak->references-1); } +static void QDECL FSPAK_AddReference(searchpathfuncs_t *handle) +{ + pack_t *pak = (void*)handle; + FTE_Atomic32_Inc(&pak->references); +} static void QDECL FSPAK_ClosePath(searchpathfuncs_t *handle) { qboolean stillopen; pack_t *pak = (void*)handle; - if (!Sys_LockMutex(pak->mutex)) - return; //ohnoes - stillopen = --pak->references > 0; - Sys_UnlockMutex(pak->mutex); + stillopen = FTE_Atomic32_Dec(&pak->references) > 0; if (stillopen) return; //not free yet @@ -260,13 +262,7 @@ static vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo vfs = Z_Malloc(sizeof(vfspack_t)); vfs->parentpak = pack; - if (!Sys_LockMutex(pack->mutex)) - { - Z_Free(vfs); - return NULL; - } - vfs->parentpak->references++; - Sys_UnlockMutex(pack->mutex); + FTE_Atomic32_Inc(&vfs->parentpak->references); vfs->startpos = loc->offset; vfs->length = loc->len; @@ -381,6 +377,7 @@ searchpathfuncs_t *QDECL FSPAK_LoadArchive (vfsfile_t *file, searchpathfuncs_t * pack->pub.fsver = FSVER; pack->pub.GetPathDetails = FSPAK_GetPathDetails; + pack->pub.AddReference = FSPAK_AddReference; pack->pub.ClosePath = FSPAK_ClosePath; pack->pub.BuildHash = FSPAK_BuildHash; pack->pub.FindFile = FSPAK_FLocate; diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index 40899f1c2..e98142558 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -583,7 +583,7 @@ typedef struct zipfile_s qofs_t rawsize; vfsfile_t *raw; - int references; //number of files open inside, so things don't crash if is closed in the wrong order. + qatomic32_t references; //number of files open inside, so things don't crash if is closed in the wrong order. } zipfile_t; @@ -599,10 +599,7 @@ static void QDECL FSZIP_GetPathDetails(searchpathfuncs_t *handle, char *out, siz static void QDECL FSZIP_UnclosePath(searchpathfuncs_t *handle) { zipfile_t *zip = (void*)handle; - if (!Sys_LockMutex(zip->mutex)) - return; //ohnoes - zip->references++; - Sys_UnlockMutex(zip->mutex); + FTE_Atomic32_Inc(&zip->references); } static void QDECL FSZIP_ClosePath(searchpathfuncs_t *handle) { @@ -610,10 +607,7 @@ static void QDECL FSZIP_ClosePath(searchpathfuncs_t *handle) qboolean stillopen; zipfile_t *zip = (void*)handle; - if (!Sys_LockMutex(zip->mutex)) - return; //ohnoes - stillopen = --zip->references > 0; - Sys_UnlockMutex(zip->mutex); + stillopen = FTE_Atomic32_Dec(&zip->references) > 0; if (stillopen) return; //not free yet @@ -1417,21 +1411,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo } } - if (Sys_LockMutex(zip->mutex)) - { - zip->references++; - Sys_UnlockMutex(zip->mutex); - } - else - { -#ifdef DO_ZIP_DECOMPRESS - if (vfsz->decompress) - vfsz->decompress->Destroy(vfsz->decompress); -#endif - Z_Free(vfsz); - return NULL; - } - + FTE_Atomic32_Inc(&zip->references); return (vfsfile_t*)vfsz; } diff --git a/engine/common/sys.h b/engine/common/sys.h index e30f349ef..63372cf4e 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -101,6 +101,20 @@ void Sys_Vibrate(float count); qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate); +#if defined(__GNUC__) + #define qatomic32_t qint32_t + #define FTE_Atomic32_Inc(ptr) __sync_add_and_fetch(ptr, 1) //returns the AFTER the operation. + #define FTE_Atomic32_Dec(ptr) __sync_add_and_fetch(ptr, 1) //returns the AFTER the operation. +#elif defined(_WIN32) + #define qatomic32_t LONG + #define FTE_Atomic32_Inc(ptr) InterlockedIncrement(ptr) + #define FTE_Atomic32_Dec(ptr) InterlockedDecrement(ptr) +#else + #define qatomic32_t qint32_t + #define FTE_Atomic32_Inc(ptr) FTE_Atomic32Mutex_Add(ptr, 1) + #define FTE_Atomic32_Dec(ptr) FTE_Atomic32Mutex_Add(ptr, -1) +#endif + #ifdef MULTITHREAD #if defined(_WIN32) && defined(_DEBUG) void Sys_SetThreadName(unsigned int dwThreadID, char *threadName);