00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackWinThread.h"
00022 #include "JackError.h"
00023 #include "JackTime.h"
00024 #include <assert.h>
00025
00026 namespace Jack
00027 {
00028
00029 DWORD WINAPI JackWinThread::ThreadHandler(void* arg)
00030 {
00031 JackWinThread* obj = (JackWinThread*)arg;
00032 JackRunnableInterface* runnable = obj->fRunnable;
00033
00034
00035 jack_log("ThreadHandler: start");
00036 obj->fStatus = kIniting;
00037
00038
00039 if (!runnable->Init()) {
00040 jack_error("Thread init fails: thread quits");
00041 return 0;
00042 }
00043
00044 obj->fStatus = kRunning;
00045
00046
00047 bool res = true;
00048 while (obj->fStatus == kRunning && res) {
00049 res = runnable->Execute();
00050 }
00051
00052 SetEvent(obj->fEvent);
00053 jack_log("ThreadHandler: exit");
00054 return 0;
00055 }
00056
00057 JackWinThread::JackWinThread(JackRunnableInterface* runnable)
00058 : JackThreadInterface(runnable, 0, false, 0)
00059 {
00060 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00061 fThread = (HANDLE)NULL;
00062 assert(fEvent);
00063 }
00064
00065 JackWinThread::~JackWinThread()
00066 {
00067 CloseHandle(fEvent);
00068 CloseHandle(fThread);
00069 }
00070
00071 int JackWinThread::Start()
00072 {
00073 fStatus = kStarting;
00074
00075
00076 if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
00077 fStatus = kIdle;
00078 return -1;
00079 } else {
00080 return 0;
00081 }
00082 }
00083
00084 int JackWinThread::StartSync()
00085 {
00086 fStatus = kStarting;
00087
00088 if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
00089 fStatus = kIdle;
00090 return -1;
00091 } else {
00092 int count = 0;
00093 while (fStatus == kStarting && ++count < 1000) {
00094 JackSleep(1000);
00095 }
00096 return (count == 1000) ? -1 : 0;
00097 }
00098 }
00099
00100 int JackWinThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg)
00101 {
00102 DWORD id;
00103 *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);
00104
00105 if (*thread == NULL) {
00106 jack_error("Cannot create thread error = %d", GetLastError());
00107 return -1;
00108 }
00109
00110 if (realtime) {
00111
00112 jack_log("Create RT thread");
00113 if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) {
00114 jack_error("Cannot set priority class = %d", GetLastError());
00115 return -1;
00116 }
00117
00118 } else {
00119 jack_log("Create non RT thread");
00120 }
00121
00122 return 0;
00123 }
00124
00125
00126
00127 int JackWinThread::Kill()
00128 {
00129 if (fThread != (HANDLE)NULL) {
00130 TerminateThread(fThread, 0);
00131 WaitForSingleObject(fThread, INFINITE);
00132 CloseHandle(fThread);
00133 jack_log("JackWinThread::Kill");
00134 fThread = (HANDLE)NULL;
00135 fStatus = kIdle;
00136 return 0;
00137 } else {
00138 return -1;
00139 }
00140 }
00141
00142 int JackWinThread::Stop()
00143 {
00144 if (fThread != (HANDLE)NULL) {
00145 jack_log("JackWinThread::Stop");
00146 fStatus = kIdle;
00147 WaitForSingleObject(fEvent, INFINITE);
00148 CloseHandle(fThread);
00149 fThread = (HANDLE)NULL;
00150 return 0;
00151 } else {
00152 return -1;
00153 }
00154 }
00155
00156 int JackWinThread::KillImp(jack_native_thread_t thread)
00157 {
00158 if (thread != (HANDLE)NULL) {
00159 TerminateThread(thread, 0);
00160 WaitForSingleObject(thread, INFINITE);
00161 CloseHandle(thread);
00162 return 0;
00163 } else {
00164 return -1;
00165 }
00166 }
00167
00168 int JackWinThread::StopImp(jack_native_thread_t thread)
00169 {
00170 if (thread) {
00171 WaitForSingleObject(thread, INFINITE);
00172 CloseHandle(thread);
00173 return 0;
00174 } else {
00175 return -1;
00176 }
00177 }
00178
00179 int JackWinThread::AcquireRealTime()
00180 {
00181 return (fThread != (HANDLE)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1;
00182 }
00183
00184 int JackWinThread::AcquireSelfRealTime()
00185 {
00186 return AcquireRealTimeImp(GetCurrentThread(), fPriority);
00187 }
00188
00189 int JackWinThread::AcquireRealTime(int priority)
00190 {
00191 fPriority = priority;
00192 return AcquireRealTime();
00193 }
00194
00195 int JackWinThread::AcquireSelfRealTime(int priority)
00196 {
00197 fPriority = priority;
00198 return AcquireSelfRealTime();
00199 }
00200
00201 int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority)
00202 {
00203 jack_log("JackWinThread::AcquireRealTime");
00204
00205 if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
00206 return 0;
00207 } else {
00208 jack_error("Cannot set thread priority = %d", GetLastError());
00209 return -1;
00210 }
00211 }
00212
00213 int JackWinThread::DropRealTime()
00214 {
00215 return (fThread != (HANDLE)NULL) ? DropRealTimeImp(fThread) : -1;
00216 }
00217
00218 int JackWinThread::DropSelfRealTime()
00219 {
00220 return DropRealTimeImp(GetCurrentThread());
00221 }
00222
00223 int JackWinThread::DropRealTimeImp(jack_native_thread_t thread)
00224 {
00225 if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
00226 return 0;
00227 } else {
00228 jack_error("Cannot set thread priority = %d", GetLastError());
00229 return -1;
00230 }
00231 }
00232
00233 jack_native_thread_t JackWinThread::GetThreadID()
00234 {
00235 return fThread;
00236 }
00237
00238 bool JackWinThread::IsThread()
00239 {
00240 return GetCurrentThread() == fThread;
00241 }
00242
00243 void JackWinThread::Terminate()
00244 {
00245 jack_log("JackWinThread::Terminate");
00246 ExitThread(0);
00247 }
00248
00249 SERVER_EXPORT void ThreadExit()
00250 {
00251 jack_log("ThreadExit");
00252 ExitThread(0);
00253 }
00254
00255 }
00256
00257 bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr)
00258 {
00259 return false;
00260 }
00261
00262 bool jack_tls_allocate_key(jack_tls_key *key_ptr)
00263 {
00264 DWORD key;
00265
00266 key = TlsAlloc();
00267 if (key == TLS_OUT_OF_INDEXES)
00268 {
00269 jack_error("TlsAlloc() failed. Error is %d", (unsigned int)GetLastError());
00270 return false;
00271 }
00272
00273 *key_ptr = key;
00274 return true;
00275 }
00276
00277 bool jack_tls_free_key(jack_tls_key key)
00278 {
00279 if (!TlsFree(key))
00280 {
00281 jack_error("TlsFree() failed. Error is %d", (unsigned int)GetLastError());
00282 return false;
00283 }
00284
00285 return true;
00286 }
00287
00288 bool jack_tls_set(jack_tls_key key, void *data_ptr)
00289 {
00290 if (!TlsSetValue(key, data_ptr))
00291 {
00292 jack_error("TlsSetValue() failed. Error is %d", (unsigned int)GetLastError());
00293 return false;
00294 }
00295
00296 return true;
00297 }
00298
00299 void *jack_tls_get(jack_tls_key key)
00300 {
00301 return TlsGetValue(key);
00302 }