forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			459 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			459 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#ifdef HX_THREAD_H_OVERRIDE
							 | 
						||
| 
								 | 
							
								// Users can define their own header to use here, but there is no API
							 | 
						||
| 
								 | 
							
								// compatibility gaurantee for future changes.
							 | 
						||
| 
								 | 
							
								#include HX_THREAD_H_OVERRIDE
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef HX_THREAD_H
							 | 
						||
| 
								 | 
							
								#define HX_THREAD_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef HXCPP_HEADER_VERSION
							 | 
						||
| 
								 | 
							
								#include "hx/HeaderVersion.h"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(KORE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/atomic.h>
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/event.h>
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/mutex.h>
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/thread.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined(HX_WINRT)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <windows.h>
							 | 
						||
| 
								 | 
							
								#include <process.h>
							 | 
						||
| 
								 | 
							
								#include <mutex>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined(_WIN32)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef HXCPP_WINXP_COMPAT
							 | 
						||
| 
								 | 
							
								#undef _WIN32_WINNT
							 | 
						||
| 
								 | 
							
								#define _WIN32_WINNT 0x0400
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#undef _WIN32_WINNT
							 | 
						||
| 
								 | 
							
								#define _WIN32_WINNT 0x0600
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <windows.h>
							 | 
						||
| 
								 | 
							
								#include <process.h>
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#include <errno.h>
							 | 
						||
| 
								 | 
							
								#include <pthread.h>
							 | 
						||
| 
								 | 
							
								#include <sys/time.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#define HXCPP_PTHREADS
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RegisterClass
							 | 
						||
| 
								 | 
							
								#undef RegisterClass
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(KORE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxMutex {
							 | 
						||
| 
								 | 
							
									HxMutex() {
							 | 
						||
| 
								 | 
							
								        kinc_mutex_init(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									~HxMutex() {
							 | 
						||
| 
								 | 
							
										kinc_mutex_destroy(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Lock() {
							 | 
						||
| 
								 | 
							
										kinc_mutex_lock(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Unlock() {
							 | 
						||
| 
								 | 
							
										kinc_mutex_unlock(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool TryLock() {
							 | 
						||
| 
								 | 
							
										return kinc_mutex_try_to_lock(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Clean() {
							 | 
						||
| 
								 | 
							
										kinc_mutex_destroy(&mutex);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									kinc_mutex_t mutex;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_TYPE void
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_RET return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline bool HxCreateDetachedThread(void (*func)(void *), void *param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    kinc_thread_t thread;
							 | 
						||
| 
								 | 
							
								    kinc_thread_init(&thread, func, param);
							 | 
						||
| 
								 | 
							
									return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined(HX_WINDOWS)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxMutex
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   HxMutex()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      mValid = true;
							 | 
						||
| 
								 | 
							
								      #ifdef HX_WINRT
							 | 
						||
| 
								 | 
							
								      InitializeCriticalSectionEx(&mCritSec,4000,0);
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								      InitializeCriticalSection(&mCritSec);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   ~HxMutex() { if (mValid) DeleteCriticalSection(&mCritSec); }
							 | 
						||
| 
								 | 
							
								   void Lock() { EnterCriticalSection(&mCritSec); }
							 | 
						||
| 
								 | 
							
								   void Unlock() { LeaveCriticalSection(&mCritSec); }
							 | 
						||
| 
								 | 
							
								   bool TryLock() { return TryEnterCriticalSection(&mCritSec); }
							 | 
						||
| 
								 | 
							
								   bool IsValid() { return mValid; }
							 | 
						||
| 
								 | 
							
								   void Clean()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      if (mValid)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         DeleteCriticalSection(&mCritSec);
							 | 
						||
| 
								 | 
							
								         mValid = false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   bool             mValid;
							 | 
						||
| 
								 | 
							
								   CRITICAL_SECTION mCritSec;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_TYPE DWORD WINAPI
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_RET return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline bool HxCreateDetachedThread(DWORD (WINAPI *func)(void *), void *param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return (CreateThread(NULL, 0, func, param, 0, 0) != 0);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxMutex
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   HxMutex()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      pthread_mutexattr_t mta;
							 | 
						||
| 
								 | 
							
								      pthread_mutexattr_init(&mta);
							 | 
						||
| 
								 | 
							
								      pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
							 | 
						||
| 
								 | 
							
								      mValid = pthread_mutex_init(&mMutex,&mta) ==0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   ~HxMutex() { if (mValid) pthread_mutex_destroy(&mMutex); }
							 | 
						||
| 
								 | 
							
								   void Lock() { pthread_mutex_lock(&mMutex); }
							 | 
						||
| 
								 | 
							
								   void Unlock() { pthread_mutex_unlock(&mMutex); }
							 | 
						||
| 
								 | 
							
								   bool TryLock() { return !pthread_mutex_trylock(&mMutex); }
							 | 
						||
| 
								 | 
							
								   bool IsValid() { return mValid; }
							 | 
						||
| 
								 | 
							
								   void Clean()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      if (mValid)
							 | 
						||
| 
								 | 
							
								         pthread_mutex_destroy(&mMutex);
							 | 
						||
| 
								 | 
							
								      mValid = 0;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   bool mValid;
							 | 
						||
| 
								 | 
							
								   pthread_mutex_t mMutex;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_TYPE void *
							 | 
						||
| 
								 | 
							
								#define THREAD_FUNC_RET return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline bool HxCreateDetachedThread(void *(*func)(void *), void *param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									pthread_t t;
							 | 
						||
| 
								 | 
							
									pthread_attr_t attr;
							 | 
						||
| 
								 | 
							
									if (pthread_attr_init(&attr) != 0)
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
								#ifdef PTHREAD_CREATE_DETACHED
							 | 
						||
| 
								 | 
							
									if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									if (pthread_create(&t, &attr, func, param) != 0 )
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									if (pthread_attr_destroy(&attr) != 0)
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<typename LOCKABLE>
							 | 
						||
| 
								 | 
							
								struct TAutoLock
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   TAutoLock(LOCKABLE &inMutex) : mMutex(inMutex) { mMutex.Lock(); }
							 | 
						||
| 
								 | 
							
								   ~TAutoLock() { mMutex.Unlock(); }
							 | 
						||
| 
								 | 
							
								   void Lock() { mMutex.Lock(); }
							 | 
						||
| 
								 | 
							
								   void Unlock() { mMutex.Unlock(); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   LOCKABLE &mMutex;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef TAutoLock<HxMutex> AutoLock;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(KORE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxSemaphore {
							 | 
						||
| 
								 | 
							
									HxSemaphore() {
							 | 
						||
| 
								 | 
							
										kinc_event_init(&event, true);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									~HxSemaphore() {
							 | 
						||
| 
								 | 
							
										kinc_event_destroy(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Set() {
							 | 
						||
| 
								 | 
							
										kinc_event_signal(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Wait() {
							 | 
						||
| 
								 | 
							
										kinc_event_wait(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool WaitSeconds(double inSeconds) {
							 | 
						||
| 
								 | 
							
										return kinc_event_try_to_wait(&event, inSeconds);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Reset() {
							 | 
						||
| 
								 | 
							
										kinc_event_reset(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Clean() {
							 | 
						||
| 
								 | 
							
										kinc_event_destroy(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									kinc_event_t event;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct ThreadPoolSignal {
							 | 
						||
| 
								 | 
							
									ThreadPoolSignal() {
							 | 
						||
| 
								 | 
							
										kinc_event_init(&event, true);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									~ThreadPoolSignal() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Set() {
							 | 
						||
| 
								 | 
							
										kinc_event_signal(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Wait() {
							 | 
						||
| 
								 | 
							
										kinc_event_wait(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool WaitSeconds(double inSeconds) {
							 | 
						||
| 
								 | 
							
										return kinc_event_try_to_wait(&event, inSeconds);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Reset() {
							 | 
						||
| 
								 | 
							
										kinc_event_reset(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void Clean() {
							 | 
						||
| 
								 | 
							
										kinc_event_destroy(&event);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									kinc_event_t event;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined(HX_WINDOWS)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxSemaphore
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   HxSemaphore()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      #ifdef HX_WINRT
							 | 
						||
| 
								 | 
							
								      mSemaphore = CreateEventEx(nullptr,nullptr,0,EVENT_ALL_ACCESS);
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								      mSemaphore = CreateEvent(0,0,0,0);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   ~HxSemaphore() { if (mSemaphore) CloseHandle(mSemaphore); }
							 | 
						||
| 
								 | 
							
								   void Set() { SetEvent(mSemaphore); }
							 | 
						||
| 
								 | 
							
								   void Wait()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      #ifdef HX_WINRT
							 | 
						||
| 
								 | 
							
								      WaitForSingleObjectEx(mSemaphore,INFINITE,false);
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								      WaitForSingleObject(mSemaphore,INFINITE);
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								    // Returns true on success, false on timeout
							 | 
						||
| 
								 | 
							
								   bool WaitSeconds(double inSeconds)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      #ifdef HX_WINRT
							 | 
						||
| 
								 | 
							
								      return WaitForSingleObjectEx(mSemaphore,inSeconds*1000.0,false) != WAIT_TIMEOUT;
							 | 
						||
| 
								 | 
							
								      #else
							 | 
						||
| 
								 | 
							
								      return WaitForSingleObject(mSemaphore,inSeconds*1000.0) != WAIT_TIMEOUT;
							 | 
						||
| 
								 | 
							
								      #endif
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void Reset() { ResetEvent(mSemaphore); }
							 | 
						||
| 
								 | 
							
								   void Clean() { if (mSemaphore) CloseHandle(mSemaphore); mSemaphore = 0; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   HANDLE mSemaphore;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define HX_THREAD_SEMAPHORE_LOCKABLE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct HxSemaphore
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   HxSemaphore()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      mSet = false;
							 | 
						||
| 
								 | 
							
								      mValid = true;
							 | 
						||
| 
								 | 
							
								      pthread_cond_init(&mCondition,0);
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   ~HxSemaphore()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      if (mValid)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         pthread_cond_destroy(&mCondition);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   // For autolock
							 | 
						||
| 
								 | 
							
								   inline operator HxMutex &() { return mMutex; }
							 | 
						||
| 
								 | 
							
								   void Set()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      AutoLock lock(mMutex);
							 | 
						||
| 
								 | 
							
								      if (!mSet)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         mSet = true;
							 | 
						||
| 
								 | 
							
								         pthread_cond_signal( &mCondition );
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void QSet()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      mSet = true;
							 | 
						||
| 
								 | 
							
								      pthread_cond_signal( &mCondition );
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void Reset()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      AutoLock lock(mMutex);
							 | 
						||
| 
								 | 
							
								      mSet = false;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void QReset() { mSet = false; }
							 | 
						||
| 
								 | 
							
								   void Wait()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      AutoLock lock(mMutex);
							 | 
						||
| 
								 | 
							
								      while( !mSet )
							 | 
						||
| 
								 | 
							
								         pthread_cond_wait( &mCondition, &mMutex.mMutex );
							 | 
						||
| 
								 | 
							
								      mSet = false;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   // when we already hold the mMutex lock ...
							 | 
						||
| 
								 | 
							
								   void QWait()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      while( !mSet )
							 | 
						||
| 
								 | 
							
								         pthread_cond_wait( &mCondition, &mMutex.mMutex );
							 | 
						||
| 
								 | 
							
								      mSet = false;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   // Returns true if the wait was success, false on timeout.
							 | 
						||
| 
								 | 
							
								   bool WaitSeconds(double inSeconds)
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      struct timeval tv;
							 | 
						||
| 
								 | 
							
								      gettimeofday(&tv, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      int isec = (int)inSeconds;
							 | 
						||
| 
								 | 
							
								      int usec = (int)((inSeconds-isec)*1000000.0);
							 | 
						||
| 
								 | 
							
								      timespec spec;
							 | 
						||
| 
								 | 
							
								      spec.tv_nsec = (tv.tv_usec + usec) * 1000;
							 | 
						||
| 
								 | 
							
								      if (spec.tv_nsec>1000000000)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         spec.tv_nsec-=1000000000;
							 | 
						||
| 
								 | 
							
								         isec++;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      spec.tv_sec = tv.tv_sec + isec;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      AutoLock lock(mMutex);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      int result = 0;
							 | 
						||
| 
								 | 
							
								      // Wait for set to be true...
							 | 
						||
| 
								 | 
							
								      while( !mSet &&  (result=pthread_cond_timedwait( &mCondition, &mMutex.mMutex, &spec )) != ETIMEDOUT)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         if (result!=0)
							 | 
						||
| 
								 | 
							
								         {
							 | 
						||
| 
								 | 
							
								            // Error - something's gone wrong...
							 | 
						||
| 
								 | 
							
								            /*
							 | 
						||
| 
								 | 
							
								            if (result==EINVAL) 
							 | 
						||
| 
								 | 
							
								               printf("ERROR: Condition EINVAL\n");
							 | 
						||
| 
								 | 
							
								            else if (result==EPERM)
							 | 
						||
| 
								 | 
							
								               printf("ERROR: Condition EPERM\n");
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								               printf("ERROR: Condition unknown error\n");
							 | 
						||
| 
								 | 
							
								            */
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         // Condition signalled - but try mSet again ...
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      bool wasSet = mSet;
							 | 
						||
| 
								 | 
							
								      mSet = false;
							 | 
						||
| 
								 | 
							
								      return wasSet;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   void Clean()
							 | 
						||
| 
								 | 
							
								   {
							 | 
						||
| 
								 | 
							
								      mMutex.Clean();
							 | 
						||
| 
								 | 
							
								      if (mValid)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								         mValid = false;
							 | 
						||
| 
								 | 
							
								         pthread_cond_destroy(&mCondition);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   HxMutex         mMutex;
							 | 
						||
| 
								 | 
							
								   pthread_cond_t  mCondition;
							 | 
						||
| 
								 | 
							
								   bool            mSet;
							 | 
						||
| 
								 | 
							
								   bool            mValid;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(KORE)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <kinc/threads/thread.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void HxSleep(unsigned int ms)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									kinc_thread_sleep(ms);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined HX_WINRT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void HxSleep(unsigned int ms)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									::Sleep(ms);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#elif defined HX_WINDOWS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void HxSleep(unsigned int ms)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									::Sleep(ms);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								inline void HxSleep(unsigned int ms)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   struct timespec t;
							 | 
						||
| 
								 | 
							
								   struct timespec tmp;
							 | 
						||
| 
								 | 
							
								   t.tv_sec = 0;
							 | 
						||
| 
								 | 
							
								   t.tv_nsec = ms * 1000000;
							 | 
						||
| 
								 | 
							
								   nanosleep(&t, &tmp);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#endif
							 |