merge latest rthreads.c from libretro-common, and improve sthread_isself to null check argument (fixes crash in winport's single-core codepaths when lua window is open)

This commit is contained in:
zeromus 2017-01-09 16:50:44 -06:00
parent 9c573370f3
commit 522a4e25d1
1 changed files with 626 additions and 572 deletions

View File

@ -43,11 +43,18 @@
#include "gx_pthread.h" #include "gx_pthread.h"
#elif defined(PSP) #elif defined(PSP)
#include "psp_pthread.h" #include "psp_pthread.h"
#elif defined(__CELLOS_LV2__)
#include <pthread.h>
#include <sys/sys_time.h>
#else #else
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#endif #endif
#if defined(VITA)
#include <sys/time.h>
#endif
#ifdef __MACH__ #ifdef __MACH__
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/mach.h> #include <mach/mach.h>
@ -154,8 +161,15 @@ sthread_t *sthread_create(void (*thread_func)(void*), void *userdata)
#ifdef USE_WIN32_THREADS #ifdef USE_WIN32_THREADS
thread->thread = CreateThread(NULL, 0, thread_wrap, data, 0, NULL); thread->thread = CreateThread(NULL, 0, thread_wrap, data, 0, NULL);
thread_created = !!thread->thread; thread_created = !!thread->thread;
#else
#if defined(VITA)
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setstacksize(&thread_attr , 0x10000 );
thread_created = pthread_create(&thread->id, &thread_attr, thread_wrap, data) == 0;
#else #else
thread_created = pthread_create(&thread->id, NULL, thread_wrap, data) == 0; thread_created = pthread_create(&thread->id, NULL, thread_wrap, data) == 0;
#endif
#endif #endif
if (!thread_created) if (!thread_created)
@ -218,15 +232,13 @@ void sthread_join(sthread_t *thread)
* sthread_isself: * sthread_isself:
* @thread : pointer to thread object * @thread : pointer to thread object
* *
* Join with a terminated thread. Waits for the thread specified by
* @thread to terminate. If that thread has already terminated, then
* it will return immediately. The thread specified by @thread must
* be joinable.
*
* Returns: true (1) if calling thread is the specified thread * Returns: true (1) if calling thread is the specified thread
*/ */
bool sthread_isself(sthread_t *thread) bool sthread_isself(sthread_t *thread)
{ {
/* This thread can't possibly be a null thread */
if (!thread) return false;
#ifdef USE_WIN32_THREADS #ifdef USE_WIN32_THREADS
return GetCurrentThread() == thread->thread; return GetCurrentThread() == thread->thread;
#else #else
@ -295,6 +307,8 @@ void slock_free(slock_t *lock)
**/ **/
void slock_lock(slock_t *lock) void slock_lock(slock_t *lock)
{ {
if (!lock)
return;
#ifdef USE_WIN32_THREADS #ifdef USE_WIN32_THREADS
WaitForSingleObject(lock->lock, INFINITE); WaitForSingleObject(lock->lock, INFINITE);
#else #else
@ -310,6 +324,8 @@ void slock_lock(slock_t *lock)
**/ **/
void slock_unlock(slock_t *lock) void slock_unlock(slock_t *lock)
{ {
if (!lock)
return;
#ifdef USE_WIN32_THREADS #ifdef USE_WIN32_THREADS
ReleaseMutex(lock->lock); ReleaseMutex(lock->lock);
#else #else
@ -547,7 +563,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
sys_time_get_current_time(&s, &n); sys_time_get_current_time(&s, &n);
now.tv_sec = s; now.tv_sec = s;
now.tv_nsec = n; now.tv_nsec = n;
#elif defined(__mips__) #elif defined(__mips__) || defined(VITA)
struct timeval tm; struct timeval tm;
gettimeofday(&tm, NULL); gettimeofday(&tm, NULL);
@ -570,3 +586,41 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
return (ret == 0); return (ret == 0);
#endif #endif
} }
#ifdef HAVE_THREAD_STORAGE
bool sthread_tls_create(sthread_tls_t *tls)
{
#ifdef USE_WIN32_THREADS
return (*tls = TlsAlloc()) != TLS_OUT_OF_INDEXES;
#else
return pthread_key_create((pthread_key_t*)tls, NULL) == 0;
#endif
}
bool sthread_tls_delete(sthread_tls_t *tls)
{
#ifdef USE_WIN32_THREADS
return TlsFree(*tls) != 0;
#else
return pthread_key_delete(*tls) == 0;
#endif
}
void *sthread_tls_get(sthread_tls_t *tls)
{
#ifdef USE_WIN32_THREADS
return TlsGetValue(*tls);
#else
return pthread_getspecific(*tls);
#endif
}
bool sthread_tls_set(sthread_tls_t *tls, const void *data)
{
#ifdef USE_WIN32_THREADS
return TlsSetValue(*tls, (void*)data) != 0;
#else
return pthread_setspecific(*tls, data) == 0;
#endif
}
#endif