// -*- C++ -*- // Copyright (C) 2009-2010, Vaclav Haisman. All rights reserved. // // Redistribution and use in source and binary forms, with or without modifica- // tion, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //! @file //! This file contains implementations of synchronization //! primitives using the Win32 API. It does not contain any include //! guards because it is only a fragment to be included by //! syncprims.h. #include namespace log4cplus { namespace thread { namespace impl { // // // inline bool InitializeCriticalSection_wrapInternal (LPCRITICAL_SECTION cs) { #if defined (_MSC_VER) __try { #endif InitializeCriticalSection (cs); #if defined (_MSC_VER) } __except (GetExceptionCode() == STATUS_NO_MEMORY ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { return false; } #endif return true; } inline void InitializeCriticalSection_wrap (LPCRITICAL_SECTION cs) { if (! InitializeCriticalSection_wrapInternal (cs)) throw std::runtime_error ( "InitializeCriticalSection: STATUS_NO_MEMORY"); } inline Mutex::Mutex (log4cplus::thread::Mutex::Type) { InitializeCriticalSection_wrap (&cs); } inline Mutex::~Mutex () { DeleteCriticalSection (&cs); } inline void Mutex::lock () const { EnterCriticalSection (&cs); } inline void Mutex::unlock () const { LeaveCriticalSection (&cs); } // // // inline Semaphore::Semaphore (unsigned max, unsigned initial) { sem = CreateSemaphore (0, initial, max, 0); if (! sem) LOG4CPLUS_THROW_RTE ("Semaphore::Semaphore"); } inline Semaphore::~Semaphore () { try { if (! CloseHandle (sem)) LOG4CPLUS_THROW_RTE ("Semaphore::~Semaphore"); } catch (...) { } } inline void Semaphore::unlock () const { DWORD ret = ReleaseSemaphore (sem, 1, 0); if (! ret) LOG4CPLUS_THROW_RTE ("Semaphore::unlock"); } inline void Semaphore::lock () const { DWORD ret = WaitForSingleObject (sem, INFINITE); if (ret != WAIT_OBJECT_0) LOG4CPLUS_THROW_RTE ("Semaphore::lock"); } // // // inline FairMutex::FairMutex () { mtx = CreateMutex (0, false, 0); if (! mtx) LOG4CPLUS_THROW_RTE ("FairMutex::FairMutex"); } inline FairMutex::~FairMutex () { try { if (! CloseHandle (mtx)) LOG4CPLUS_THROW_RTE ("FairMutex::~FairMutex"); } catch (...) { } } inline void FairMutex::lock () const { DWORD ret = WaitForSingleObject (mtx, INFINITE); if (ret != WAIT_OBJECT_0) LOG4CPLUS_THROW_RTE ("FairMutex::lock"); } inline void FairMutex::unlock () const { if (! ReleaseMutex (mtx)) LOG4CPLUS_THROW_RTE ("FairMutex::unlock"); } // // // inline ManualResetEvent::ManualResetEvent (bool sig) { ev = CreateEvent (0, true, sig, 0); if (! ev) LOG4CPLUS_THROW_RTE ("ManualResetEvent::ManualResetEvent"); } inline ManualResetEvent::~ManualResetEvent () { try { if (! CloseHandle (ev)) LOG4CPLUS_THROW_RTE ("ManualResetEvent::~ManualResetEvent"); } catch (...) { } } inline void ManualResetEvent::signal () const { if (! SetEvent (ev)) LOG4CPLUS_THROW_RTE ("ManualResetEVent::signal"); } inline void ManualResetEvent::wait () const { DWORD ret = WaitForSingleObject (ev, INFINITE); if (ret != WAIT_OBJECT_0) LOG4CPLUS_THROW_RTE ("ManualResetEvent::wait"); } inline bool ManualResetEvent::timed_wait (unsigned long msec) const { DWORD ret = WaitForSingleObject (ev, static_cast(msec)); switch(ret) { case WAIT_OBJECT_0: return true; case WAIT_TIMEOUT: return false; default: LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait"); // Silence warnings about not returning any value from function // returning bool. return false; } } inline void ManualResetEvent::reset () const { if (! ResetEvent (ev)) LOG4CPLUS_THROW_RTE ("ManualResetEvent::reset"); } // // // #if defined (LOG4CPLUS_POOR_MANS_SHAREDMUTEX) #include "log4cplus/thread/impl/syncprims-pmsm.h" #else inline SharedMutex::SharedMutex () { InitializeSRWLock (&srwl); } inline SharedMutex::~SharedMutex () { } inline void SharedMutex::rdlock () const { AcquireSRWLockShared (&srwl); } inline void SharedMutex::rdunlock () const { ReleaseSRWLockShared (&srwl); } inline void SharedMutex::wrlock () const { AcquireSRWLockExclusive (&srwl); } inline void SharedMutex::wrunlock () const { ReleaseSRWLockExclusive (&srwl); } #endif } } } // namespace log4cplus { namespace thread { namespace impl {