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 <assert.h>
00024
00025 namespace Jack
00026 {
00027
00028 DWORD WINAPI JackWinThread::ThreadHandler(void* arg)
00029 {
00030 JackWinThread* obj = (JackWinThread*)arg;
00031 JackRunnableInterface* runnable = obj->fRunnable;
00032
00033
00034 if (!runnable->Init()) {
00035 jack_error("Thread init fails: thread quits");
00036 return 0;
00037 }
00038
00039
00040 if (!obj->fRunning) {
00041 obj->fRunning = true;
00042 SetEvent(obj->fEvent);
00043 }
00044
00045 JackLog("ThreadHandler: start\n");
00046
00047
00048 bool res = true;
00049 while (obj->fRunning && res) {
00050 res = runnable->Execute();
00051 }
00052
00053 SetEvent(obj->fEvent);
00054 JackLog("ThreadHandler: exit\n");
00055 return 0;
00056 }
00057
00058 JackWinThread::JackWinThread(JackRunnableInterface* runnable)
00059 : JackThread(runnable, 0, false, 0)
00060 {
00061 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00062 fThread = NULL;
00063 assert(fEvent);
00064 }
00065
00066 JackWinThread::~JackWinThread()
00067 {
00068 CloseHandle(fEvent);
00069 }
00070
00071 int JackWinThread::Start()
00072 {
00073 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00074 if (fEvent == NULL) {
00075 jack_error("Cannot create event error = %d", GetLastError());
00076 return -1;
00077 }
00078
00079 fRunning = true;
00080
00081
00082 if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
00083 fRunning = false;
00084 return -1;
00085 } else {
00086 return 0;
00087 }
00088 }
00089
00090 int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg)
00091 {
00092 DWORD id;
00093
00094 if (realtime) {
00095
00096 JackLog("Create RT thread\n");
00097 *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);
00098
00099 if (*thread == NULL) {
00100 jack_error("Cannot create thread error = %d", GetLastError());
00101 return -1;
00102 }
00103
00104 if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) {
00105 jack_error("Cannot set priority class = %d", GetLastError());
00106 return -1;
00107 }
00108
00109 return 0;
00110
00111 } else {
00112
00113 JackLog("Create non RT thread\n");
00114 *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);
00115
00116 if (thread == NULL) {
00117 jack_error("Cannot create thread error = %d", GetLastError());
00118 return -1;
00119 }
00120
00121 return 0;
00122 }
00123 }
00124
00125 int JackWinThread::StartSync()
00126 {
00127 DWORD id;
00128
00129 fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
00130 if (fEvent == NULL) {
00131 jack_error("Cannot create event error = %d", GetLastError());
00132 return -1;
00133 }
00134
00135 if (fRealTime) {
00136
00137 JackLog("Create RT thread\n");
00138 fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00139
00140 if (fThread == NULL) {
00141 jack_error("Cannot create thread error = %d", GetLastError());
00142 return -1;
00143 }
00144
00145 if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) {
00146 jack_error("Thread has not started");
00147 return -1;
00148 }
00149
00150 if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
00151 jack_error("Cannot set priority class = %d", GetLastError());
00152 return -1;
00153 }
00154
00155 return 0;
00156
00157 } else {
00158
00159 JackLog("Create non RT thread\n");
00160 fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
00161
00162 if (fThread == NULL) {
00163 jack_error("Cannot create thread error = %d", GetLastError());
00164 return -1;
00165 }
00166
00167 if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) {
00168 jack_error("Thread has not started");
00169 return -1;
00170 }
00171
00172 return 0;
00173 }
00174 }
00175
00176
00177
00178 int JackWinThread::Kill()
00179 {
00180 if (fThread) {
00181 TerminateThread(fThread, 0);
00182 WaitForSingleObject(fThread, INFINITE);
00183 CloseHandle(fThread);
00184 JackLog("JackWinThread::Kill 2\n");
00185 fThread = NULL;
00186 fRunning = false;
00187 return 0;
00188 } else {
00189 return -1;
00190 }
00191 }
00192
00193 int JackWinThread::Stop()
00194 {
00195 if (fThread) {
00196 JackLog("JackWinThread::Stop\n");
00197 fRunning = false;
00198 WaitForSingleObject(fEvent, INFINITE);
00199 CloseHandle(fThread);
00200 fThread = NULL;
00201 return 0;
00202 } else {
00203 return -1;
00204 }
00205 }
00206
00207 int JackWinThread::AcquireRealTime()
00208 {
00209 return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1;
00210 }
00211
00212 int JackWinThread::AcquireRealTime(int priority)
00213 {
00214 fPriority = priority;
00215 return AcquireRealTime();
00216 }
00217
00218 int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority)
00219 {
00220 JackLog("JackWinThread::AcquireRealTime\n");
00221
00222 if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
00223 JackLog("JackWinThread::AcquireRealTime OK\n");
00224 return 0;
00225 } else {
00226 jack_error("Cannot set thread priority = %d", GetLastError());
00227 return -1;
00228 }
00229 }
00230 int JackWinThread::DropRealTime()
00231 {
00232 return DropRealTimeImp(fThread);
00233 }
00234
00235 int JackWinThread::DropRealTimeImp(pthread_t thread)
00236 {
00237 if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
00238 return 0;
00239 } else {
00240 jack_error("Cannot set thread priority = %d", GetLastError());
00241 return -1;
00242 }
00243 }
00244
00245 pthread_t JackWinThread::GetThreadID()
00246 {
00247 return fThread;
00248 }
00249
00250 void JackWinThread::Terminate()
00251 {
00252 TerminateThread(fThread, 0);
00253 WaitForSingleObject(fThread, INFINITE);
00254 CloseHandle(fThread);
00255 }
00256
00257 }
00258