mirror of
https://github.com/yawut/SDL.git
synced 2026-09-07 08:36:19 -05:00
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
This commit is contained in:
@@ -31,125 +31,133 @@
|
||||
|
||||
struct SDL_cond
|
||||
{
|
||||
pthread_cond_t cond;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
/* Create a condition variable */
|
||||
SDL_cond * SDL_CreateCond(void)
|
||||
SDL_cond *
|
||||
SDL_CreateCond(void)
|
||||
{
|
||||
SDL_cond *cond;
|
||||
SDL_cond *cond;
|
||||
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if ( cond ) {
|
||||
if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
return(cond);
|
||||
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
|
||||
if (cond) {
|
||||
if (pthread_cond_init(&cond->cond, NULL) < 0) {
|
||||
SDL_SetError("pthread_cond_init() failed");
|
||||
SDL_free(cond);
|
||||
cond = NULL;
|
||||
}
|
||||
}
|
||||
return (cond);
|
||||
}
|
||||
|
||||
/* Destroy a condition variable */
|
||||
void SDL_DestroyCond(SDL_cond *cond)
|
||||
void
|
||||
SDL_DestroyCond(SDL_cond * cond)
|
||||
{
|
||||
if ( cond ) {
|
||||
pthread_cond_destroy(&cond->cond);
|
||||
SDL_free(cond);
|
||||
}
|
||||
if (cond) {
|
||||
pthread_cond_destroy(&cond->cond);
|
||||
SDL_free(cond);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart one of the threads that are waiting on the condition variable */
|
||||
int SDL_CondSignal(SDL_cond *cond)
|
||||
int
|
||||
SDL_CondSignal(SDL_cond * cond)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
if (!cond) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_signal(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_signal() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
retval = 0;
|
||||
if (pthread_cond_signal(&cond->cond) != 0) {
|
||||
SDL_SetError("pthread_cond_signal() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Restart all threads that are waiting on the condition variable */
|
||||
int SDL_CondBroadcast(SDL_cond *cond)
|
||||
int
|
||||
SDL_CondBroadcast(SDL_cond * cond)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
if (!cond) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
|
||||
SDL_SetError("pthread_cond_broadcast() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
retval = 0;
|
||||
if (pthread_cond_broadcast(&cond->cond) != 0) {
|
||||
SDL_SetError("pthread_cond_broadcast() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
|
||||
int
|
||||
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
|
||||
{
|
||||
int retval;
|
||||
struct timeval delta;
|
||||
struct timespec abstime;
|
||||
int retval;
|
||||
struct timeval delta;
|
||||
struct timespec abstime;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
if (!cond) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gettimeofday(&delta, NULL);
|
||||
gettimeofday(&delta, NULL);
|
||||
|
||||
abstime.tv_sec = delta.tv_sec + (ms/1000);
|
||||
abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
|
||||
if ( abstime.tv_nsec > 1000000000 ) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
abstime.tv_sec = delta.tv_sec + (ms / 1000);
|
||||
abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
|
||||
if (abstime.tv_nsec > 1000000000) {
|
||||
abstime.tv_sec += 1;
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
|
||||
switch (retval) {
|
||||
case EINTR:
|
||||
goto tryagain;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("pthread_cond_timedwait() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
|
||||
switch (retval) {
|
||||
case EINTR:
|
||||
goto tryagain;
|
||||
break;
|
||||
case ETIMEDOUT:
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("pthread_cond_timedwait() failed");
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Wait on the condition variable, unlocking the provided mutex.
|
||||
The mutex must be locked before entering this function!
|
||||
*/
|
||||
int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
|
||||
int
|
||||
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! cond ) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
if (!cond) {
|
||||
SDL_SetError("Passed a NULL condition variable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
|
||||
SDL_SetError("pthread_cond_wait() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
retval = 0;
|
||||
if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
|
||||
SDL_SetError("pthread_cond_wait() failed");
|
||||
retval = -1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -30,124 +30,131 @@
|
||||
#define FAKE_RECURSIVE_MUTEX
|
||||
#endif
|
||||
|
||||
struct SDL_mutex {
|
||||
pthread_mutex_t id;
|
||||
struct SDL_mutex
|
||||
{
|
||||
pthread_mutex_t id;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
int recursive;
|
||||
pthread_t owner;
|
||||
int recursive;
|
||||
pthread_t owner;
|
||||
#endif
|
||||
};
|
||||
|
||||
SDL_mutex *SDL_CreateMutex (void)
|
||||
SDL_mutex *
|
||||
SDL_CreateMutex(void)
|
||||
{
|
||||
SDL_mutex *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
SDL_mutex *mutex;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
/* Allocate the structure */
|
||||
mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex));
|
||||
if ( mutex ) {
|
||||
pthread_mutexattr_init(&attr);
|
||||
/* Allocate the structure */
|
||||
mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex));
|
||||
if (mutex) {
|
||||
pthread_mutexattr_init(&attr);
|
||||
#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP
|
||||
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
||||
#else
|
||||
/* No extra attributes necessary */
|
||||
/* No extra attributes necessary */
|
||||
#endif
|
||||
if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) {
|
||||
SDL_SetError("pthread_mutex_init() failed");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return(mutex);
|
||||
if (pthread_mutex_init(&mutex->id, &attr) != 0) {
|
||||
SDL_SetError("pthread_mutex_init() failed");
|
||||
SDL_free(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return (mutex);
|
||||
}
|
||||
|
||||
void SDL_DestroyMutex(SDL_mutex *mutex)
|
||||
void
|
||||
SDL_DestroyMutex(SDL_mutex * mutex)
|
||||
{
|
||||
if ( mutex ) {
|
||||
pthread_mutex_destroy(&mutex->id);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
if (mutex) {
|
||||
pthread_mutex_destroy(&mutex->id);
|
||||
SDL_free(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the mutex */
|
||||
int SDL_mutexP(SDL_mutex *mutex)
|
||||
int
|
||||
SDL_mutexP(SDL_mutex * mutex)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
pthread_t this_thread;
|
||||
pthread_t this_thread;
|
||||
#endif
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if (mutex == NULL) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
retval = 0;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
this_thread = pthread_self();
|
||||
if ( mutex->owner == this_thread ) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if ( pthread_mutex_lock(&mutex->id) == 0 ) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
this_thread = pthread_self();
|
||||
if (mutex->owner == this_thread) {
|
||||
++mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
We set the locking thread id after we obtain the lock
|
||||
so unlocks from other threads will fail.
|
||||
*/
|
||||
if (pthread_mutex_lock(&mutex->id) == 0) {
|
||||
mutex->owner = this_thread;
|
||||
mutex->recursive = 0;
|
||||
} else {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( pthread_mutex_lock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
if (pthread_mutex_lock(&mutex->id) < 0) {
|
||||
SDL_SetError("pthread_mutex_lock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_mutexV(SDL_mutex *mutex)
|
||||
int
|
||||
SDL_mutexV(SDL_mutex * mutex)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( mutex == NULL ) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
if (mutex == NULL) {
|
||||
SDL_SetError("Passed a NULL mutex");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
retval = 0;
|
||||
#if FAKE_RECURSIVE_MUTEX
|
||||
/* We can only unlock the mutex if we own it */
|
||||
if ( pthread_self() == mutex->owner ) {
|
||||
if ( mutex->recursive ) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
pthread_mutex_unlock(&mutex->id);
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("mutex not owned by this thread");
|
||||
retval = -1;
|
||||
}
|
||||
/* We can only unlock the mutex if we own it */
|
||||
if (pthread_self() == mutex->owner) {
|
||||
if (mutex->recursive) {
|
||||
--mutex->recursive;
|
||||
} else {
|
||||
/* The order of operations is important.
|
||||
First reset the owner so another thread doesn't lock
|
||||
the mutex and set the ownership before we reset it,
|
||||
then release the lock semaphore.
|
||||
*/
|
||||
mutex->owner = 0;
|
||||
pthread_mutex_unlock(&mutex->id);
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("mutex not owned by this thread");
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
#else
|
||||
if ( pthread_mutex_unlock(&mutex->id) < 0 ) {
|
||||
SDL_SetError("pthread_mutex_unlock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
if (pthread_mutex_unlock(&mutex->id) < 0) {
|
||||
SDL_SetError("pthread_mutex_unlock() failed");
|
||||
retval = -1;
|
||||
}
|
||||
#endif /* FAKE_RECURSIVE_MUTEX */
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#ifndef _SDL_mutex_c_h
|
||||
#define _SDL_mutex_c_h
|
||||
|
||||
struct SDL_mutex {
|
||||
pthread_mutex_t id;
|
||||
struct SDL_mutex
|
||||
{
|
||||
pthread_mutex_t id;
|
||||
};
|
||||
|
||||
#endif /* _SDL_mutex_c_h */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
@@ -35,122 +34,132 @@
|
||||
#include "../generic/SDL_syssem.c"
|
||||
#else
|
||||
|
||||
struct SDL_semaphore {
|
||||
sem_t sem;
|
||||
struct SDL_semaphore
|
||||
{
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
/* Create a semaphore, initialized with value */
|
||||
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||
SDL_sem *
|
||||
SDL_CreateSemaphore(Uint32 initial_value)
|
||||
{
|
||||
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
|
||||
if ( sem ) {
|
||||
if ( sem_init(&sem->sem, 0, initial_value) < 0 ) {
|
||||
SDL_SetError("sem_init() failed");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return sem;
|
||||
SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem));
|
||||
if (sem) {
|
||||
if (sem_init(&sem->sem, 0, initial_value) < 0) {
|
||||
SDL_SetError("sem_init() failed");
|
||||
SDL_free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
return sem;
|
||||
}
|
||||
|
||||
void SDL_DestroySemaphore(SDL_sem *sem)
|
||||
void
|
||||
SDL_DestroySemaphore(SDL_sem * sem)
|
||||
{
|
||||
if ( sem ) {
|
||||
sem_destroy(&sem->sem);
|
||||
SDL_free(sem);
|
||||
}
|
||||
if (sem) {
|
||||
sem_destroy(&sem->sem);
|
||||
SDL_free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_SemTryWait(SDL_sem *sem)
|
||||
int
|
||||
SDL_SemTryWait(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
if ( sem_trywait(&sem->sem) == 0 ) {
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
retval = SDL_MUTEX_TIMEDOUT;
|
||||
if (sem_trywait(&sem->sem) == 0) {
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWait(SDL_sem *sem)
|
||||
int
|
||||
SDL_SemWait(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ( ((retval = sem_wait(&sem->sem)) == -1) && (errno == EINTR) ) {}
|
||||
if ( retval < 0 ) {
|
||||
SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
retval = sem_wait(&sem->sem);
|
||||
if (retval < 0) {
|
||||
SDL_SetError("sem_wait() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||
int
|
||||
SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try the easy cases first */
|
||||
if ( timeout == 0 ) {
|
||||
return SDL_SemTryWait(sem);
|
||||
}
|
||||
if ( timeout == SDL_MUTEX_MAXWAIT ) {
|
||||
return SDL_SemWait(sem);
|
||||
}
|
||||
/* Try the easy cases first */
|
||||
if (timeout == 0) {
|
||||
return SDL_SemTryWait(sem);
|
||||
}
|
||||
if (timeout == SDL_MUTEX_MAXWAIT) {
|
||||
return SDL_SemWait(sem);
|
||||
}
|
||||
|
||||
/* Ack! We have to busy wait... */
|
||||
/* FIXME: Use sem_timedwait()? */
|
||||
timeout += SDL_GetTicks();
|
||||
do {
|
||||
retval = SDL_SemTryWait(sem);
|
||||
if ( retval == 0 ) {
|
||||
break;
|
||||
}
|
||||
SDL_Delay(1);
|
||||
} while ( SDL_GetTicks() < timeout );
|
||||
/* Ack! We have to busy wait... */
|
||||
/* FIXME: Use sem_timedwait()? */
|
||||
timeout += SDL_GetTicks();
|
||||
do {
|
||||
retval = SDL_SemTryWait(sem);
|
||||
if (retval == 0) {
|
||||
break;
|
||||
}
|
||||
SDL_Delay(1);
|
||||
}
|
||||
while (SDL_GetTicks() < timeout);
|
||||
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||
Uint32
|
||||
SDL_SemValue(SDL_sem * sem)
|
||||
{
|
||||
int ret = 0;
|
||||
if ( sem ) {
|
||||
sem_getvalue(&sem->sem, &ret);
|
||||
if ( ret < 0 ) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return (Uint32)ret;
|
||||
int ret = 0;
|
||||
if (sem) {
|
||||
sem_getvalue(&sem->sem, &ret);
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return (Uint32) ret;
|
||||
}
|
||||
|
||||
int SDL_SemPost(SDL_sem *sem)
|
||||
int
|
||||
SDL_SemPost(SDL_sem * sem)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
if ( ! sem ) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
if (!sem) {
|
||||
SDL_SetError("Passed a NULL semaphore");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = sem_post(&sem->sem);
|
||||
if ( retval < 0 ) {
|
||||
SDL_SetError("sem_post() failed");
|
||||
}
|
||||
return retval;
|
||||
retval = sem_post(&sem->sem);
|
||||
if (retval < 0) {
|
||||
SDL_SetError("sem_post() failed");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* __MACOSX__ */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -30,91 +30,99 @@
|
||||
|
||||
/* List of signals to mask in the subthreads */
|
||||
static int sig_list[] = {
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
|
||||
SIGVTALRM, SIGPROF, 0
|
||||
SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH,
|
||||
SIGVTALRM, SIGPROF, 0
|
||||
};
|
||||
|
||||
#ifdef __RISCOS__
|
||||
/* RISC OS needs to know the main thread for
|
||||
* it's timer and event processing. */
|
||||
int riscos_using_threads = 0;
|
||||
Uint32 riscos_main_thread = 0; /* Thread running events */
|
||||
Uint32 riscos_main_thread = 0; /* Thread running events */
|
||||
#endif
|
||||
|
||||
|
||||
static void *RunThread(void *data)
|
||||
|
||||
static void *
|
||||
RunThread(void *data)
|
||||
{
|
||||
SDL_RunThread(data);
|
||||
pthread_exit((void*)0);
|
||||
return((void *)0); /* Prevent compiler warning */
|
||||
SDL_RunThread(data);
|
||||
pthread_exit((void *) 0);
|
||||
return ((void *) 0); /* Prevent compiler warning */
|
||||
}
|
||||
|
||||
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||
int
|
||||
SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
|
||||
{
|
||||
pthread_attr_t type;
|
||||
pthread_attr_t type;
|
||||
|
||||
/* Set the thread attributes */
|
||||
if ( pthread_attr_init(&type) != 0 ) {
|
||||
SDL_SetError("Couldn't initialize pthread attributes");
|
||||
return(-1);
|
||||
}
|
||||
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
/* Create the thread and go! */
|
||||
if ( pthread_create(&thread->handle, &type, RunThread, args) != 0 ) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return(-1);
|
||||
}
|
||||
/* Set the thread attributes */
|
||||
if (pthread_attr_init(&type) != 0) {
|
||||
SDL_SetError("Couldn't initialize pthread attributes");
|
||||
return (-1);
|
||||
}
|
||||
pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
/* Create the thread and go! */
|
||||
if (pthread_create(&thread->handle, &type, RunThread, args) != 0) {
|
||||
SDL_SetError("Not enough resources to create thread");
|
||||
return (-1);
|
||||
}
|
||||
#ifdef __RISCOS__
|
||||
if (riscos_using_threads == 0) {
|
||||
riscos_using_threads = 1;
|
||||
riscos_main_thread = SDL_ThreadID();
|
||||
}
|
||||
if (riscos_using_threads == 0) {
|
||||
riscos_using_threads = 1;
|
||||
riscos_main_thread = SDL_ThreadID();
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void SDL_SYS_SetupThread(void)
|
||||
void
|
||||
SDL_SYS_SetupThread(void)
|
||||
{
|
||||
int i;
|
||||
sigset_t mask;
|
||||
int i;
|
||||
sigset_t mask;
|
||||
|
||||
/* Mask asynchronous signals for this thread */
|
||||
sigemptyset(&mask);
|
||||
for ( i=0; sig_list[i]; ++i ) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
pthread_sigmask(SIG_BLOCK, &mask, 0);
|
||||
/* Mask asynchronous signals for this thread */
|
||||
sigemptyset(&mask);
|
||||
for (i = 0; sig_list[i]; ++i) {
|
||||
sigaddset(&mask, sig_list[i]);
|
||||
}
|
||||
pthread_sigmask(SIG_BLOCK, &mask, 0);
|
||||
|
||||
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
/* Allow ourselves to be asynchronously cancelled */
|
||||
{ int oldstate;
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
|
||||
}
|
||||
/* Allow ourselves to be asynchronously cancelled */
|
||||
{
|
||||
int oldstate;
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* WARNING: This may not work for systems with 64-bit pid_t */
|
||||
Uint32 SDL_ThreadID(void)
|
||||
Uint32
|
||||
SDL_ThreadID(void)
|
||||
{
|
||||
return((Uint32)pthread_self());
|
||||
return ((Uint32) pthread_self());
|
||||
}
|
||||
|
||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||
void
|
||||
SDL_SYS_WaitThread(SDL_Thread * thread)
|
||||
{
|
||||
pthread_join(thread->handle, 0);
|
||||
pthread_join(thread->handle, 0);
|
||||
}
|
||||
|
||||
void SDL_SYS_KillThread(SDL_Thread *thread)
|
||||
void
|
||||
SDL_SYS_KillThread(SDL_Thread * thread)
|
||||
{
|
||||
#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
|
||||
pthread_cancel(thread->handle);
|
||||
pthread_cancel(thread->handle);
|
||||
#else
|
||||
#ifdef __FREEBSD__
|
||||
#warning For some reason, this doesnt actually kill a thread - FreeBSD 3.2
|
||||
#endif
|
||||
pthread_kill(thread->handle, SIGKILL);
|
||||
pthread_kill(thread->handle, SIGKILL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -24,3 +24,4 @@
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_t SYS_ThreadHandle;
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
Reference in New Issue
Block a user