mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-29 06:07:57 +03:00
Added gamespy SDK
This commit is contained in:
parent
294ca5ffd2
commit
dd44f78fc5
642 changed files with 186078 additions and 0 deletions
212
code/gamespy/common/linux/gsThreadLinux.c
Normal file
212
code/gamespy/common/linux/gsThreadLinux.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
//
|
||||
// Linux Threading Support (pthreads)
|
||||
//
|
||||
// NOTE: when implementing this make sure the "-lpthread" compiler option is used
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "../gsPlatformUtil.h"
|
||||
#include "../gsPlatformThread.h"
|
||||
#include "../gsAssert.h"
|
||||
#include "../gsDebug.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#define _REENTRANT
|
||||
|
||||
#define PTHREAD_NO_ERROR 0
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// These functions are unsupported in the current version of the SDK
|
||||
|
||||
gsi_u32 gsiInterlockedIncrement(gsi_u32 * value)
|
||||
{
|
||||
GS_ASSERT_STR(gsi_false, "gsiInterlockIncrement is unsupported for LINUX in the current version of the SDK\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gsi_u32 gsiInterlockedDecrement(gsi_u32 * value)
|
||||
{
|
||||
GS_ASSERT_STR(gsi_false, "gsiInterlockIncrement is unsupported for LINUX in the current version of the SDK\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
int gsiStartThread(GSThreadFunc func, gsi_u32 theStackSize, void *arg, GSIThreadID * id)
|
||||
{
|
||||
pthread_attr_init(&id->attr);
|
||||
pthread_attr_setstacksize(&id->attr, theStackSize);
|
||||
|
||||
if (pthread_create(&id->thread, &id->attr, (void *)func, arg) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to create thread\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gsiCancelThread(GSIThreadID id)
|
||||
{
|
||||
//should i destroy the attributes here?
|
||||
pthread_attr_destroy(&id.attr);
|
||||
|
||||
if (pthread_cancel(id.thread) != PTHREAD_NO_ERROR) {
|
||||
//there was an error - how should we handle these? or should we?
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to cancel thread\r\n");
|
||||
}
|
||||
//free up memory and set to NULL
|
||||
|
||||
gsifree(&id.thread);
|
||||
}
|
||||
|
||||
// This must be called from INSIDE the thread you wish to exit
|
||||
void gsiExitThread(GSIThreadID id)
|
||||
{
|
||||
// detach the thread so that it knows to free resources upon exit
|
||||
pthread_detach(id.thread);
|
||||
|
||||
// exit thread to free up resources
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void gsiCleanupThread(GSIThreadID id)
|
||||
{
|
||||
// destroy any leftover attributes associated with the thread
|
||||
pthread_attr_destroy(&id.attr);
|
||||
}
|
||||
|
||||
gsi_u32 gsiHasThreadShutdown(GSIThreadID id)
|
||||
{
|
||||
// pthreads lacks detection mechanism for this
|
||||
GSI_UNUSED(id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void gsiInitializeCriticalSection(GSICriticalSection *theCrit)
|
||||
{
|
||||
if (pthread_mutex_init(theCrit, NULL) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to initialize critical section\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void gsiEnterCriticalSection(GSICriticalSection *theCrit)
|
||||
{
|
||||
if (pthread_mutex_lock(theCrit) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to lock mutex for entering critical section\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void gsiLeaveCriticalSection(GSICriticalSection *theCrit)
|
||||
{
|
||||
if (pthread_mutex_unlock(theCrit) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to unlock mutex for leaving critical section\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void gsiDeleteCriticalSection(GSICriticalSection *theCrit)
|
||||
{
|
||||
if (pthread_mutex_destroy(theCrit) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to destroy mutex\r\n");
|
||||
}
|
||||
theCrit = NULL;
|
||||
}
|
||||
|
||||
GSISemaphoreID gsiCreateSemaphore(gsi_i32 theInitialCount, gsi_i32 theMaxCount, char* theName)
|
||||
{
|
||||
int result;
|
||||
GSISemaphoreID semaphore;
|
||||
|
||||
//we can use the default attributes for the mutex by passing NULL
|
||||
result = pthread_mutex_init(&semaphore.mLock, NULL);
|
||||
|
||||
if (result != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to create semaphore\r\n");
|
||||
}
|
||||
|
||||
semaphore.mValue = theInitialCount;
|
||||
semaphore.mMax = theMaxCount;
|
||||
|
||||
GSI_UNUSED(theName);
|
||||
return semaphore;
|
||||
}
|
||||
|
||||
// Waits for -- and signals -- the semaphore
|
||||
gsi_u32 gsiWaitForSemaphore(GSISemaphoreID theSemaphore, gsi_u32 theTimeoutMs)
|
||||
{
|
||||
gsi_time startTime = current_time();
|
||||
gsi_bool infinite = (theTimeoutMs == GSI_INFINITE)?gsi_true:gsi_false;
|
||||
|
||||
do
|
||||
{
|
||||
//try to lock, if it doesn't then its busy
|
||||
if(pthread_mutex_trylock(&theSemaphore.mLock) == PTHREAD_NO_ERROR)
|
||||
{
|
||||
if(theSemaphore.mValue > 0)
|
||||
{
|
||||
theSemaphore.mValue--;
|
||||
pthread_mutex_unlock(&theSemaphore.mLock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&theSemaphore.mLock);
|
||||
}
|
||||
|
||||
if(theTimeoutMs != 0)
|
||||
msleep(2);
|
||||
|
||||
} while(gsi_is_true(infinite) || ((current_time() - startTime) < theTimeoutMs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allow other objects to access the semaphore
|
||||
void gsiReleaseSemaphore(GSISemaphoreID theSemaphore, gsi_i32 theReleaseCount)
|
||||
{
|
||||
if(pthread_mutex_trylock(&theSemaphore.mLock) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to lock semaphore\r\n");
|
||||
|
||||
GSI_UNUSED(theReleaseCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
theSemaphore.mValue += theReleaseCount;
|
||||
if(theSemaphore.mValue > theSemaphore.mMax)
|
||||
theSemaphore.mValue = theSemaphore.mMax;
|
||||
|
||||
pthread_mutex_unlock(&theSemaphore.mLock);
|
||||
}
|
||||
}
|
||||
|
||||
void gsiCloseSemaphore(GSISemaphoreID theSemaphore)
|
||||
{
|
||||
if (pthread_mutex_destroy(&theSemaphore.mLock) != PTHREAD_NO_ERROR)
|
||||
{
|
||||
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Misc, GSIDebugLevel_WarmError,
|
||||
"Failed to destroy semaphore\r\n");
|
||||
GSI_UNUSED(theSemaphore);
|
||||
}
|
||||
|
||||
//need to free up memory
|
||||
gsifree(&theSemaphore.mValue);
|
||||
gsifree(&theSemaphore.mMax);
|
||||
gsifree(&theSemaphore);
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue