Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

WaitSet.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // Lamp : Open source game middleware
00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //------------------------------------------------------------------------------
00019 
00020 /** @file
00021  * ウェイトセット実装
00022  * @author Junpee
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 } // End of namespace Lamp
00119 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:38 2005 for Lamp by doxygen 1.3.2