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 = 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(pthread_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) {
00130 TerminateThread(fThread, 0);
00131 WaitForSingleObject(fThread, INFINITE);
00132 CloseHandle(fThread);
00133 jack_log("JackWinThread::Kill");
00134 fThread = NULL;
00135 fStatus = kIdle;
00136 return 0;
00137 } else {
00138 return -1;
00139 }
00140 }
00141
00142 int JackWinThread::Stop()
00143 {
00144 if (fThread) {
00145 jack_log("JackWinThread::Stop");
00146 fStatus = kIdle;
00147 WaitForSingleObject(fEvent, INFINITE);
00148 CloseHandle(fThread);
00149 fThread = NULL;
00150 return 0;
00151 } else {
00152 return -1;
00153 }
00154 }
00155
00156 int JackWinThread::KillImp(pthread_t thread)
00157 {
00158 if (thread) {
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(pthread_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) ? AcquireRealTimeImp(fThread, fPriority) : -1;
00182 }
00183
00184 int JackWinThread::AcquireRealTime(int priority)
00185 {
00186 fPriority = priority;
00187 return AcquireRealTime();
00188 }
00189
00190 int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority)
00191 {
00192 jack_log("JackWinThread::AcquireRealTime");
00193
00194 if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
00195 return 0;
00196 } else {
00197 jack_error("Cannot set thread priority = %d", GetLastError());
00198 return -1;
00199 }
00200 }
00201 int JackWinThread::DropRealTime()
00202 {
00203 return DropRealTimeImp(fThread);
00204 }
00205
00206 int JackWinThread::DropRealTimeImp(pthread_t thread)
00207 {
00208 if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
00209 return 0;
00210 } else {
00211 jack_error("Cannot set thread priority = %d", GetLastError());
00212 return -1;
00213 }
00214 }
00215
00216 pthread_t JackWinThread::GetThreadID()
00217 {
00218 return fThread;
00219 }
00220
00221 void JackWinThread::Terminate()
00222 {
00223 jack_log("JackWinThread::Terminate");
00224 ExitThread(0);
00225 }
00226
00227 SERVER_EXPORT void ThreadExit()
00228 {
00229 jack_log("ThreadExit");
00230 ExitThread(0);
00231 }
00232
00233 }
00234
00235 bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr)
00236 {
00237 return false;
00238 }
00239
00240 bool jack_tls_allocate_key(jack_tls_key *key_ptr)
00241 {
00242 DWORD key;
00243
00244 key = TlsAlloc();
00245 if (key == TLS_OUT_OF_INDEXES)
00246 {
00247 jack_error("TlsAlloc() failed. Error is %d", (unsigned int)GetLastError());
00248 return false;
00249 }
00250
00251 *key_ptr = key;
00252 return true;
00253 }
00254
00255 bool jack_tls_free_key(jack_tls_key key)
00256 {
00257 if (!TlsFree(key))
00258 {
00259 jack_error("TlsFree() failed. Error is %d", (unsigned int)GetLastError());
00260 return false;
00261 }
00262
00263 return true;
00264 }
00265
00266 bool jack_tls_set(jack_tls_key key, void *data_ptr)
00267 {
00268 if (!TlsSetValue(key, data_ptr))
00269 {
00270 jack_error("TlsSetValue() failed. Error is %d", (unsigned int)GetLastError());
00271 return false;
00272 }
00273
00274 return true;
00275 }
00276
00277 void *jack_tls_get(jack_tls_key key)
00278 {
00279 return TlsGetValue(key);
00280 }