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 #include "LampBasic.h"
00026 #include <process.h>
00027 #include "Core/Thread/Thread.h"
00028 #include "Core/Thread/SynchronizedBlock.h"
00029
00030
00031 #include <windows.h>
00032 #pragma comment(lib, "winmm.lib")
00033
00034 namespace Lamp{
00035
00036
00037
00038
00039
00040
00041 u_int __stdcall threadCallback(void* userData){
00042 Thread* thread = (Thread*)userData;
00043 return thread->executeWrapper();
00044 }
00045
00046
00047 const HANDLE Thread::invalidThreadHandle = (HANDLE)-1L;
00048
00049
00050
00051
00052
00053 void Thread::initialize(){
00054
00055 ::timeBeginPeriod(1);
00056 }
00057
00058
00059 void Thread::finalize(){
00060
00061 ::timeEndPeriod(1);
00062 }
00063
00064
00065 Thread::Thread() : Runnable(),
00066 threadHandle_(invalidThreadHandle), threadID_(0), isFinished_(false){
00067 runnable_ = this;
00068 createThread();
00069 }
00070
00071
00072 Thread::Thread(Runnable* runnable) : Runnable(),
00073 threadHandle_(invalidThreadHandle), threadID_(0), isFinished_(false){
00074 runnable_ = runnable;
00075 createThread();
00076 }
00077
00078
00079 Thread::Thread(LockObject* lockObject, bool deleteLockObject) :
00080 Runnable(lockObject, deleteLockObject),
00081 threadHandle_(invalidThreadHandle), threadID_(0), isFinished_(false){
00082 runnable_ = this;
00083 createThread();
00084 }
00085
00086
00087 Thread::Thread(
00088 Runnable* runnable, LockObject* lockObject, bool deleteLockObject) :
00089 Runnable(lockObject, deleteLockObject),
00090 threadHandle_(invalidThreadHandle), threadID_(0), isFinished_(false){
00091 runnable_ = runnable;
00092 createThread();
00093 }
00094
00095
00096 Thread::~Thread(){
00097 Assert(isFinished_);
00098 }
00099
00100
00101 void Thread::createThread(){
00102
00103 Assert(threadHandle_ == invalidThreadHandle);
00104 Assert(threadID_ == 0);
00105 threadHandle_ = (HANDLE)::_beginthreadex(NULL, getStackSize(),
00106 threadCallback, this, CREATE_SUSPENDED, &threadID_);
00107 if(threadHandle_ == invalidThreadHandle){
00108 ErrorOut("Thread::createThread() _beginthreadex()に失敗しました");
00109 }
00110 isFinished_ = false;
00111 }
00112
00113
00114
00115
00116 void Thread::start(){
00117
00118 SynchronizedBlock synchronizedBlock(this);
00119
00120 if(isFinished_){ createThread(); }
00121 Assert(getThreadHandle() != invalidThreadHandle);
00122 Assert(getThreadID() != 0);
00123 if(::ResumeThread(getThreadHandle()) == 0xFFFFFFFF){
00124 ErrorOut("Thread::start() ResumeThread()に失敗しました");
00125 }
00126 }
00127
00128
00129 void Thread::setup(){
00130
00131 SynchronizedBlock synchronizedBlock(this);
00132
00133 if(isFinished_){ createThread(); }
00134 Assert(getThreadHandle() != invalidThreadHandle);
00135 Assert(getThreadID() != 0);
00136 }
00137
00138
00139 void Thread::requestStop(){
00140
00141 SynchronizedBlock synchronizedBlock(this);
00142 if(isFinished()){ return; }
00143 Assert(getThreadHandle() != invalidThreadHandle);
00144 Assert(getThreadID() != 0);
00145 runnable_->setStopRequested(true);
00146 }
00147
00148
00149 bool Thread::stop(u_int milliseconds){
00150 if(isFinished()){ return true; }
00151 requestStop();
00152 return join(milliseconds);
00153 }
00154
00155
00156 bool Thread::join(u_int milliseconds){
00157
00158 if(isFinished()){ return true; }
00159 Assert(getThreadHandle() != invalidThreadHandle);
00160 Assert(getThreadID() != 0);
00161 u_int result = ::WaitForSingleObject(getThreadHandle(), milliseconds);
00162 if(result == WAIT_OBJECT_0){
00163 return true;
00164 }else if(result == WAIT_TIMEOUT){
00165 return false;
00166 }else if(result == WAIT_ABANDONED){
00167 ErrorOut("Thread::join() Mutexを保持したままThreadが終了しました");
00168 }else if(result == WAIT_FAILED){
00169 Assert(false);
00170 return false;
00171
00172
00173 }
00174 return true;
00175 }
00176
00177
00178 void Thread::setPriority(Priority priority){
00179 Assert(getThreadHandle() != invalidThreadHandle);
00180 Assert(getThreadID() != 0);
00181
00182 SynchronizedBlock synchronizedBlock(this);
00183 if(SetThreadPriority(getThreadHandle(), priority) == 0){
00184 ErrorOut("Thread::setPriority() SetThreadPriority()に失敗しました");
00185 }
00186 }
00187
00188
00189 Thread::Priority Thread::getPriority(){
00190 Assert(getThreadHandle() != invalidThreadHandle);
00191 Assert(getThreadID() != 0);
00192
00193 SynchronizedBlock synchronizedBlock(this);
00194 int result = GetThreadPriority(getThreadHandle());
00195 if(result == THREAD_PRIORITY_ERROR_RETURN){
00196 ErrorOut("Thread::getPriority() GetThreadPriority()に失敗しました");
00197 }
00198 return (Priority)result;
00199 }
00200
00201
00202 void Thread::suspend(){
00203
00204 SynchronizedBlock synchronizedBlock(this);
00205 if(isFinished()){ return; }
00206 Assert(::GetCurrentThreadId() != getThreadID());
00207 if(::SuspendThread(getThreadHandle()) == 0xFFFFFFFF){
00208 ErrorOut("Thread::suspend() SuspendThread()に失敗しました");
00209 }
00210 }
00211
00212
00213 void Thread::resume(){
00214
00215 SynchronizedBlock synchronizedBlock(this);
00216 if(isFinished()){ return; }
00217 if(::ResumeThread(getThreadHandle()) == 0xFFFFFFFF){
00218 ErrorOut("Thread::resume() ResumeThread()に失敗しました");
00219 }
00220 }
00221
00222
00223
00224
00225 u_int Thread::executeWrapper(){
00226
00227 {
00228
00229 SynchronizedBlock synchronizedBlock(this);
00230 runnable_->setStopRequested(false);
00231 }
00232
00233 runnable_->run(this);
00234
00235 {
00236
00237 SynchronizedBlock synchronizedBlock(this);
00238 isFinished_ = true;
00239 ::CloseHandle(getThreadHandle());
00240 threadHandle_ = invalidThreadHandle;
00241 threadID_ = 0;
00242 }
00243 return 0;
00244 }
00245
00246 }
00247