#ifndef JMUTEX_H 
  
 #define JMUTEX_H 
  
 #if (defined(WIN32) || defined(_WIN32_WCE)) 
         #ifndef _WIN32_WCE 
                 #include <process.h> 
         #endif // _WIN32_WCE 
         #include <winsock2.h> 
         #include <windows.h> 
  
         #define JMUTEX_CRITICALSECTION 
 #else // using pthread 
         #include <pthread.h> 
 #endif // WIN32 
  
 #define ERR_JMUTEX_ALREADYINIT                                          -1 
 #define ERR_JMUTEX_NOTINIT                                              -2 
 #define ERR_JMUTEX_CANTCREATEMUTEX                                      -3 
  
 class JMutex 
 { 
 public: 
         JMutex(); 
         ~JMutex(); 
         int Init(); 
         int Lock(); 
         int Unlock(); 
         bool IsInitialized()                                            { return initialized; } 
 private: 
 #if (defined(WIN32) || defined(_WIN32_WCE)) 
 #ifdef JMUTEX_CRITICALSECTION 
         CRITICAL_SECTION mutex; 
 #else // Use standard mutex 
         HANDLE mutex; 
 #endif // JMUTEX_CRITICALSECTION 
 #else // pthread mutex 
         pthread_mutex_t mutex; 
 #endif // WIN32 
         bool initialized; 
 }; 
  
 #endif // JMUTEX_H #ifndef JTHREAD_H 
  
 #define JTHREAD_H 
  
 #include "jmutex.h" 
  
 #define ERR_JTHREAD_CANTINITMUTEX                                               -1 
 #define ERR_JTHREAD_CANTSTARTTHREAD                                             -2 
 #define ERR_JTHREAD_THREADFUNCNOTSET                                            -3 
 #define ERR_JTHREAD_NOTRUNNING                                                  -4 
 #define ERR_JTHREAD_ALREADYRUNNING                                              -5 
  
 class JThread 
 { 
 public: 
         JThread(); 
         virtual ~JThread(); 
         int Start(); 
         int Kill(); 
         virtual void *Thread() = 0; 
         bool IsRunning(); 
         void *GetReturnValue(); 
 protected: 
         void ThreadStarted(); 
 private: 
  
 #if (defined(WIN32) || defined(_WIN32_WCE)) 
 #ifdef _WIN32_WCE 
         DWORD threadid; 
         static DWORD WINAPI TheThread(void *param); 
 #else 
         static UINT __stdcall TheThread(void *param); 
         UINT threadid; 
 #endif // _WIN32_WCE 
         HANDLE threadhandle; 
 #else // pthread type threads 
         static void *TheThread(void *param); 
          
         pthread_t threadid; 
 #endif // WIN32 
         void *retval; 
         bool running; 
          
         JMutex runningmutex; 
         JMutex continuemutex,continuemutex2; 
         bool mutexinit; 
 }; 
  
 #endif // JTHREAD_H #include "jmutex.h" 
  
 JMutex::JMutex() 
 { 
         initialized = false; 
         Init(); 
 } 
  
 JMutex::~JMutex() 
 { 
         if (initialized) 
 #ifdef JMUTEX_CRITICALSECTION 
                 DeleteCriticalSection(&mutex); 
 #else 
                 CloseHandle(mutex); 
 #endif // JMUTEX_CRITICALSECTION 
 } 
  
 int JMutex::Init() 
 { 
         if (initialized) 
                 return ERR_JMUTEX_ALREADYINIT; 
 #ifdef JMUTEX_CRITICALSECTION 
         InitializeCriticalSection(&mutex); 
 #else 
         mutex = CreateMutex(NULL,FALSE,NULL); 
         if (mutex == NULL) 
                 return ERR_JMUTEX_CANTCREATEMUTEX; 
 #endif // JMUTEX_CRITICALSECTION 
         initialized = true; 
         return 0; 
 } 
  
 int JMutex::Lock() 
 { 
         if (!initialized) 
                 return ERR_JMUTEX_NOTINIT; 
 #ifdef JMUTEX_CRITICALSECTION 
         EnterCriticalSection(&mutex); 
 #else 
         WaitForSingleObject(mutex,INFINITE); 
 #endif // JMUTEX_CRITICALSECTION 
         return 0; 
 } 
  
 int JMutex::Unlock() 
 { 
         if (!initialized) 
                 return ERR_JMUTEX_NOTINIT; 
 #ifdef JMUTEX_CRITICALSECTION 
         LeaveCriticalSection(&mutex); 
 #else 
         ReleaseMutex(mutex); 
 #endif // JMUTEX_CRITICALSECTION 
         return 0; 
 } #include "jthread.h" 
  
 #ifndef _WIN32_WCE 
         #include <process.h> 
 #endif // _WIN32_WCE 
  
 JThread::JThread() 
 { 
         retval = NULL; 
         mutexinit = false; 
         running = false; 
 } 
  
 JThread::~JThread() 
 { 
         Kill(); 
 } 
  
 int JThread::Start() 
 { 
         if (!mutexinit) 
         { 
                 if (!runningmutex.IsInitialized()) 
                 { 
                         if (runningmutex.Init() < 0) 
                                 return ERR_JTHREAD_CANTINITMUTEX; 
                 } 
                 if (!continuemutex.IsInitialized()) 
                 { 
                         if (continuemutex.Init() < 0) 
                                 return ERR_JTHREAD_CANTINITMUTEX; 
                 } 
                 if (!continuemutex2.IsInitialized()) 
                 { 
                         if (continuemutex2.Init() < 0) 
                                 return ERR_JTHREAD_CANTINITMUTEX; 
                 }               mutexinit = true; 
         } 
          
         runningmutex.Lock(); 
         if (running) 
         { 
                 runningmutex.Unlock(); 
                 return ERR_JTHREAD_ALREADYRUNNING; 
         } 
         runningmutex.Unlock(); 
          
         continuemutex.Lock(); 
 #ifndef _WIN32_WCE 
         threadhandle = (HANDLE)_beginthreadex(NULL,0,TheThread,this,0,&threadid); 
 #else 
         threadhandle = CreateThread(NULL,0,TheThread,this,0,&threadid); 
 #endif // _WIN32_WCE 
         if (threadhandle == NULL) 
         { 
                 continuemutex.Unlock(); 
                 return ERR_JTHREAD_CANTSTARTTHREAD; 
         } 
          
         /* Wait until 'running' is set */ 
  
         runningmutex.Lock();                     
         while (!running) 
         { 
                 runningmutex.Unlock(); 
                 Sleep(1); 
                 runningmutex.Lock(); 
         } 
         runningmutex.Unlock(); 
          
         continuemutex.Unlock(); 
          
         continuemutex2.Lock(); 
         continuemutex2.Unlock(); 
                  
         return 0; 
 } 
  
 int JThread::Kill() 
 { 
         runningmutex.Lock();                     
         if (!running) 
         { 
                 runningmutex.Unlock(); 
                 return ERR_JTHREAD_NOTRUNNING; 
         } 
         TerminateThread(threadhandle,0); 
         CloseHandle(threadhandle); 
         running = false; 
         runningmutex.Unlock(); 
         return 0; 
 } 
  
 bool JThread::IsRunning() 
 { 
         bool r; 
          
         runningmutex.Lock();                     
         r = running; 
         runningmutex.Unlock(); 
         return r; 
 } 
  
 void *JThread::GetReturnValue() 
 { 
         void *val; 
          
         runningmutex.Lock(); 
         if (running) 
                 val = NULL; 
         else 
                 val = retval; 
         runningmutex.Unlock(); 
         return val; 
 } 
  
 #ifndef _WIN32_WCE 
 UINT __stdcall JThread::TheThread(void *param) 
 #else 
 DWORD WINAPI JThread::TheThread(void *param) 
 #endif // _WIN32_WCE 
 { 
         JThread *jthread; 
         void *ret; 
  
         jthread = (JThread *)param; 
          
         jthread->continuemutex2.Lock(); 
         jthread->runningmutex.Lock(); 
         jthread->running = true; 
         jthread->runningmutex.Unlock(); 
          
         jthread->continuemutex.Lock(); 
         jthread->continuemutex.Unlock(); 
          
         ret = jthread->Thread(); 
          
         jthread->runningmutex.Lock(); 
         jthread->running = false; 
         jthread->retval = ret; 
         CloseHandle(jthread->threadhandle); 
         jthread->runningmutex.Unlock(); 
         return 0;                
 } 
  
 void JThread::ThreadStarted() 
 { 
         continuemutex2.Unlock(); 
 }