dthread-win.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "common/h/dthread.h"
00031 #include <assert.h>
00032
00033 DThread::DThread()
00034 {
00035 }
00036
00037 DThread::~DThread()
00038 {
00039 }
00040
00041 long DThread::self()
00042 {
00043 return (long)::GetCurrentThread();
00044 }
00045 bool DThread::spawn(DThread::initial_func_t func, void *param)
00046 {
00047 thrd = ::CreateThread(NULL, 0, func, param, 0, NULL);
00048 live = (thrd != INVALID_HANDLE_VALUE);
00049 return live;
00050 }
00051 bool DThread::join()
00052 {
00053 assert(live && self() != id());
00054 ::WaitForSingleObject(thrd, INFINITE);
00055 return true;
00056 }
00057
00058 long DThread::id()
00059 {
00060 return (long)thrd;
00061 }
00062
00063
00064 Mutex::Mutex(bool recursive)
00065 {
00066 mutex = ::CreateMutex(NULL, false, NULL);
00067 }
00068
00069 Mutex::~Mutex()
00070 {
00071 ::CloseHandle(mutex);
00072 }
00073
00074 bool Mutex::lock()
00075 {
00076 return (::WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0);
00077 }
00078
00079 bool Mutex::unlock()
00080 {
00081 return ::ReleaseMutex(mutex);
00082 }
00083
00084 CondVar::CondVar(Mutex *m) :
00085 numWaiting(0),
00086 was_broadcast(false),
00087 mutex(m),
00088 created_mutex(false)
00089 {
00090 if(mutex == NULL)
00091 {
00092 mutex = new Mutex();
00093 created_mutex = true;
00094 }
00095 wait_sema = ::CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
00096 ::InitializeCriticalSection(&numWaitingLock);
00097 wait_done = ::CreateEvent(NULL, false, false, NULL);
00098 }
00099 CondVar::~CondVar()
00100 {
00101 if(created_mutex)
00102 {
00103 delete mutex;
00104 }
00105 ::CloseHandle(wait_sema);
00106 ::CloseHandle(wait_done);
00107 }
00108
00109 bool CondVar::unlock()
00110 {
00111 mutex->unlock();
00112 return true;
00113 }
00114 bool CondVar::lock()
00115 {
00116 mutex->lock();
00117 return true;
00118 }
00119 bool CondVar::signal()
00120 {
00121 mutex->lock();
00122 ::EnterCriticalSection(&numWaitingLock);
00123 bool waitingThreads = (numWaiting > 0);
00124 ::LeaveCriticalSection(&numWaitingLock);
00125 if(waitingThreads)
00126 {
00127 ::ReleaseSemaphore(wait_sema, 1, 0);
00128 }
00129 mutex->unlock();
00130 return true;
00131 }
00132 bool CondVar::broadcast()
00133 {
00134 mutex->lock();
00135 ::EnterCriticalSection(&numWaitingLock);
00136 bool waitingThreads = (numWaiting > 0);
00137 was_broadcast = true;
00138 if(waitingThreads)
00139 {
00140 ::ReleaseSemaphore(wait_sema, 1, 0);
00141 ::LeaveCriticalSection(&numWaitingLock);
00142 ::WaitForSingleObject(wait_done, INFINITE);
00143 was_broadcast = false;
00144 }
00145 else
00146 {
00147 ::LeaveCriticalSection(&numWaitingLock);
00148 }
00149 mutex->unlock();
00150 return true;
00151 }
00152 bool CondVar::wait()
00153 {
00154 mutex->lock();
00155 ::EnterCriticalSection(&numWaitingLock);
00156 numWaiting++;
00157 ::LeaveCriticalSection(&numWaitingLock);
00158 ::SignalObjectAndWait(mutex->mutex, wait_sema, INFINITE, FALSE);
00159 ::EnterCriticalSection(&numWaitingLock);
00160 numWaiting--;
00161 bool last_waiter = (was_broadcast && (numWaiting == 0));
00162 ::LeaveCriticalSection(&numWaitingLock);
00163 if(last_waiter)
00164 {
00165 ::SignalObjectAndWait(wait_done, mutex->mutex, INFINITE, FALSE);
00166 }
00167 else
00168 {
00169 ::WaitForSingleObject(mutex->mutex, INFINITE);
00170 }
00171 mutex->unlock();
00172 return true;
00173 }