diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index d839a32..8aa5443 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -372,6 +372,17 @@ void ILibDispatchSemaphore_trywait(sem_t* s) { dispatch_semaphore_wait(((dispatch_semaphore_t*)s)[0], DISPATCH_TIME_NOW); } +int ILibDispatchSemaphore_timedwait(sem_t* s, struct timespec *ts) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + uint64_t seconds = ts->tv_sec - tv.tv_sec; + uint64_t ns = ts->tv_nsec - (tv.tv_usec * 1000); + uint64_t delta = ns + (seconds * 1000000000); + + return((int)dispatch_semaphore_wait(((dispatch_semaphore_t*)s)[0], dispatch_time(DISPATCH_TIME_NOW, (int64_t)delta))); +} void ILibDispatchSemaphore_post(sem_t* s) { dispatch_semaphore_signal(((dispatch_semaphore_t*)s)[0]); @@ -9412,6 +9423,31 @@ void ILIBLOGMESSAGEX(char *format, ...) ILIBLOGMESSSAGE(dest); } + +#ifdef __APPLE__ +typedef struct ILibThread_AppleThread +{ + pthread_t tid; + voidfp1 method; + void *arg; + int joinable; + sem_t s; +}ILibThread_AppleThread; +void* ILibThread_AppleThread_Start(void *arg) +{ + ILibThread_AppleThread *apple = (ILibThread_AppleThread*)arg; + apple->method(apple->arg); + if (apple->joinable != 0) + { + sem_post(&(apple->s)); + } + else + { + ILibMemory_Free(apple); + } + return(NULL); +} +#endif //! Platform Agnostic method to Spawn a detached worker thread with normal priority/affinity /*! \param method Handler to dispatch on the new thread @@ -9420,15 +9456,25 @@ void ILIBLOGMESSAGEX(char *format, ...) */ void* ILibSpawnNormalThreadEx(voidfp1 method, void* arg, int detached) { -#if defined (_POSIX) || defined (__APPLE__) +#if defined (_POSIX) intptr_t result; void* (*fptr) (void* a); pthread_t newThread; fptr = (void*(*)(void*))method; +#if defined(__APPLE__) + ILibThread_AppleThread *ret = (ILibThread_AppleThread*)ILibMemory_SmartAllocate(sizeof(ILibThread_AppleThread)); + ret->method = method; ret->arg = arg; + if (detached != 0) { sem_init(&(ret->s), 0, 0); ret->joinable = 1; } + result = (intptr_t)pthread_create(&newThread, NULL, ILibThread_AppleThread_Start, ret); + ret->tid = newThread; + if (detached != 0) { pthread_detach(newThread); } + return(ret); +#else result = (intptr_t)pthread_create(&newThread, NULL, fptr, arg); if (detached != 0) { pthread_detach(newThread); } return(result == 0 ? (void*)newThread : NULL); #endif +#endif #ifdef WIN32 return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)method, arg, 0, NULL ); @@ -9442,7 +9488,18 @@ void* ILibSpawnNormalThreadEx(voidfp1 method, void* arg, int detached) #ifndef WIN32 int ILibThread_TimedJoinEx(void *thr, struct timespec* timeout) { +#ifdef __APPLE__ + int ret = 1; + if (ILibMemory_CanaryOK(thr) && ((ILibThread_AppleThread*)thr)->joinable != 0) + { + ILibThread_AppleThread *ath = (ILibThread_AppleThread*)thr; + if ((ret = sem_timedwait(&(ath->s), timeout)) == 0) { sem_destroy(&(ath->s)); } + ILibMemory_Free(thr); + } + return(ret); +#else return(pthread_timedjoin_np((pthread_t)thr, NULL, timeout)); +#endif } struct timespec *ILibThread_ms2ts(uint32_t ms, struct timespec *ts) { @@ -9450,7 +9507,7 @@ struct timespec *ILibThread_ms2ts(uint32_t ms, struct timespec *ts) long lv; gettimeofday(&tv, NULL); - ts->tv_sec = tv.tv_sec + (ms / 1000); + ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; ts->tv_sec += (ms / 1000); @@ -9480,8 +9537,15 @@ void ILibThread_Join(void *thr) #ifdef WIN32 WaitForSingleObject((HANDLE)thr, INFINITE); #else - void *r; - pthread_join((pthread_t)thr, &r); + #ifdef __APPLE__ + if (ILibMemory_CanaryOK(thr) && ((ILibThread_AppleThread*)thr)->joinable!=0) + { + pthread_join(((ILibThread_AppleThread*)thr)->tid, NULL); + ILibMemory_Free(thr); + } + #else + pthread_join((pthread_t)thr, NULL); + #endif #endif } diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index d3f8cb0..8346a1e 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -143,10 +143,12 @@ struct sockaddr_in6; #define sem_wait(x) ILibDispatchSemaphore_wait(x) #define sem_trywait(x) ILibDispatchSemaphore_trywait(s) #define sem_post(x) ILibDispatchSemaphore_post(x) +#define sem_timedwait(x, timeout) ILibDispatchSemaphore_timedwait(x, timeout) void ILibDispatchSemaphore_Init(sem_t* s, int pShared, int value); void ILibDispatchSemaphore_Destroy(sem_t* s); void ILibDispatchSemaphore_wait(sem_t* s); void ILibDispatchSemaphore_trywait(sem_t* s); +int ILibDispatchSemaphore_timedwait(sem_t *x, struct timespec *timeout); void ILibDispatchSemaphore_post(sem_t* s); #endif