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 "Core/Thread/WaitSet.h"
00027 #include "Core/Thread/CriticalSection.h"
00028 #include "Core/Thread/Thread.h"
00029
00030 namespace Lamp{
00031
00032
00033
00034 WaitSet::WaitSet() : deleteLockObject_(true){
00035 lockObject_ = new CriticalSection();
00036 }
00037
00038
00039 WaitSet::WaitSet(LockObject* lockObject, bool deleteLockObject) :
00040 lockObject_(lockObject), deleteLockObject_(deleteLockObject){
00041 Assert(lockObject_ != NULL);
00042 }
00043
00044
00045 WaitSet::~WaitSet(){
00046 Assert(waitingThreads_.getCount() == 0);
00047 if(deleteLockObject_){ delete lockObject_; }
00048 }
00049
00050
00051 void WaitSet::wait(const Thread* thread){
00052 if(!isLockedByCurrentThread()){
00053 ErrorOut("WaitSet::wait() "
00054 "wait()するためにはWaitSetに対するlock()が必要です");
00055 }
00056 HANDLE threadHandle = thread->getThreadHandle();
00057 waitingThreads_.pushBack(threadHandle);
00058 unlock();
00059 if(::SuspendThread(threadHandle) == 0xFFFFFFFF){
00060 ErrorOut("WaitSet::wait() SuspendThread()に失敗しました");
00061 }
00062 lock();
00063 }
00064
00065
00066 void WaitSet::wait(){
00067 if(!isLockedByCurrentThread()){
00068 ErrorOut("WaitSet::wait() "
00069 "wait()するためにはWaitSetに対するlock()が必要です");
00070 }
00071
00072 HANDLE threadHandle;
00073 if(::DuplicateHandle(::GetCurrentProcess(), ::GetCurrentThread(),
00074 ::GetCurrentProcess(), &threadHandle,
00075 0, false, DUPLICATE_SAME_ACCESS) == 0){
00076 ErrorOut("WaitSet::wait() DuplicateHandle()に失敗しました");
00077 }
00078 waitingThreads_.pushBack(threadHandle);
00079 unlock();
00080 if(::SuspendThread(threadHandle) == 0xFFFFFFFF){
00081 ErrorOut("WaitSet::wait() SuspendThread()に失敗しました");
00082 }
00083 lock();
00084
00085 ::CloseHandle(threadHandle);
00086 }
00087
00088
00089 void WaitSet::notify(){
00090 if(!isLockedByCurrentThread()){
00091 ErrorOut("WaitSet::notify() "
00092 "notify()するためにはWaitSetに対するlock()が必要です");
00093 }
00094 if(waitingThreads_.getCount() == 0){ return; }
00095 HANDLE threadHandle = waitingThreads_.popFront();
00096 if(::ResumeThread(threadHandle) == 0xFFFFFFFF){
00097 ErrorOut("WaitSet::notify() ResumeThread()に失敗しました");
00098 }
00099 }
00100
00101
00102 void WaitSet::notifyAll(){
00103 if(!isLockedByCurrentThread()){
00104 ErrorOut("WaitSet::notifyAll() "
00105 "notifyAll()するためにはWaitSetに対するlock()が必要です");
00106 }
00107 int threadCount = waitingThreads_.getCount();
00108 if(threadCount == 0){ return; }
00109 for(int i = 0; i < threadCount; i++){
00110 HANDLE threadHandle = waitingThreads_.get(i);
00111 if(::ResumeThread(threadHandle) == 0xFFFFFFFF){
00112 ErrorOut("WaitSet::notifyAll() ResumeThread()に失敗しました");
00113 }
00114 }
00115 waitingThreads_.clear();
00116 }
00117
00118 }
00119