//  // // ##### #### # # -= Threadux =-  // //  # # # ## ## Gate.cpp  // //  # # # ##  // //  # # # ### Gate which can be used to halt threads until they are  // //  # # # ## ## allowed to pass  // //  # #### # # R1 2004 by Markus Ewald  // //  // #include "Threadux/Gate.h" #include #define WIN32_LEAN_AND_MEAN #include using namespace Threadux; namespace { // ############################################################################################# // // # handleWaitError() # // // ############################################################################################# // /// Handles errors while waiting for a win32 event handle void handleWaitError(DWORD WaitResult) { switch(WaitResult) { case WAIT_TIMEOUT: { throw Gate::TimeoutError("Gate not opened within timeout period"); } case WAIT_ABANDONED: { throw std::runtime_error("Gate was abandoned while waiting for it"); } default: { throw std::logic_error("Gate is in an undefined state"); } } } } // anonymous namespace // ############################################################################################# // // # Threadux::Gate::Gate() # // // ############################################################################################# // Gate::Gate(bool bInitiallyOpen, bool bWatergate) : m_pImpl(0) { HANDLE hEvent = ::CreateEvent(NULL, !bWatergate, bInitiallyOpen, NULL); if(!hEvent) { DWORD Error = ::GetLastError(); throw std::runtime_error("Failed to create Win32 event object"); } m_pImpl = reinterpret_cast(hEvent); } // ############################################################################################# // // # Threadux::Gate::~Gate() # // // ############################################################################################# // Gate::~Gate() { if(m_pImpl) ::CloseHandle(reinterpret_cast(m_pImpl)); } // ############################################################################################# // // # Threadux::Gate::passAllOf() # // // ############################################################################################# // void Gate::passAllOf(Gate *pFirst, size_t Count, size_t WaitTimeoutMS) { assert(sizeof(*pFirst) == sizeof(HANDLE)); DWORD WaitResult = ::WaitForMultipleObjects( static_cast(Count), reinterpret_cast(pFirst), true, static_cast(WaitTimeoutMS) ); if(WaitResult != WAIT_OBJECT_0) handleWaitError(WaitResult); } // ############################################################################################# // // # Threadux::Gate::passOneOf() # // // ############################################################################################# // size_t Gate::passOneOf(Gate *pFirst, size_t Count, size_t WaitTimeoutMS) { assert(sizeof(*pFirst) == sizeof(HANDLE)); DWORD WaitResult = ::WaitForMultipleObjects( static_cast(Count), reinterpret_cast(pFirst), false, static_cast(WaitTimeoutMS) ); if((WaitResult < WAIT_OBJECT_0) || (WaitResult >= WAIT_OBJECT_0 + Count)) handleWaitError(WaitResult); return WAIT_OBJECT_0 - WaitResult; } // ############################################################################################# // // # Threadux::Gate::pass() # // // ############################################################################################# // void Gate::pass(size_t WaitTimeoutMS) { passOneOf(this, 1, WaitTimeoutMS); } // ############################################################################################# // // # Threadux::Gate::open() # // // ############################################################################################# // void Gate::open() { if(!::SetEvent(reinterpret_cast(m_pImpl))) { DWORD Error = ::GetLastError(); throw std::runtime_error("Failed to set Win32 event object to signalled"); } } // ############################################################################################# // // # Threadux::Gate::close() # // // ############################################################################################# // void Gate::close() { if(!::ResetEvent(reinterpret_cast(m_pImpl))) { DWORD Error = ::GetLastError(); throw std::runtime_error("Failed to set Win32 event object to signalled"); } }