You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							328 lines
						
					
					
						
							5.8 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							328 lines
						
					
					
						
							5.8 KiB
						
					
					
				
								// -*- 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 <stdexcept>
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								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<DWORD>(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 {
							 |