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.
		
		
		
		
		
			
		
			
				
					
					
						
							382 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							382 lines
						
					
					
						
							6.7 KiB
						
					
					
				
								// -*- C++ -*-
							 | 
						|
								//  Copyright (C) 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.
							 | 
						|
								
							 | 
						|
								#ifndef LOG4CPLUS_THREAD_SYNCPRIMS_H
							 | 
						|
								#define LOG4CPLUS_THREAD_SYNCPRIMS_H
							 | 
						|
								
							 | 
						|
								#include <log4cplus/config.hxx>
							 | 
						|
								
							 | 
						|
								#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
							 | 
						|
								#pragma once
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								namespace log4cplus { namespace thread {
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								class SyncGuard
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    SyncGuard ();
							 | 
						|
								    SyncGuard (SP const &);
							 | 
						|
								    ~SyncGuard ();
							 | 
						|
								
							 | 
						|
								    void lock ();
							 | 
						|
								    void unlock ();
							 | 
						|
								    void attach (SP const &);
							 | 
						|
								    void attach_and_lock (SP const &);
							 | 
						|
								    void detach ();
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    SP const * sp;
							 | 
						|
								
							 | 
						|
								    SyncGuard (SyncGuard const &);
							 | 
						|
								    SyncGuard & operator = (SyncGuard const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class ManualResetEvent;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class MutexImplBase
							 | 
						|
								{
							 | 
						|
								protected:
							 | 
						|
								    ~MutexImplBase ();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class LOG4CPLUS_EXPORT Mutex
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    enum Type
							 | 
						|
								    {
							 | 
						|
								        DEFAULT,
							 | 
						|
								        RECURSIVE
							 | 
						|
								    };
							 | 
						|
								
							 | 
						|
								    explicit Mutex (Type = RECURSIVE);
							 | 
						|
								    ~Mutex ();
							 | 
						|
								
							 | 
						|
								    void lock () const;
							 | 
						|
								    void unlock () const;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    MutexImplBase * mtx;
							 | 
						|
								
							 | 
						|
								    Mutex (Mutex const &);
							 | 
						|
								    Mutex & operator = (Mutex &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef SyncGuard<Mutex> MutexGuard;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class SemaphoreImplBase
							 | 
						|
								{
							 | 
						|
								protected:
							 | 
						|
								    ~SemaphoreImplBase ();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class LOG4CPLUS_EXPORT Semaphore
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    Semaphore (unsigned max, unsigned initial);
							 | 
						|
								    ~Semaphore ();
							 | 
						|
								
							 | 
						|
								    void lock () const;
							 | 
						|
								    void unlock () const;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    SemaphoreImplBase * sem;
							 | 
						|
								
							 | 
						|
								    Semaphore (Semaphore const &);
							 | 
						|
								    Semaphore & operator = (Semaphore const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef SyncGuard<Semaphore> SemaphoreGuard;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class FairMutexImplBase
							 | 
						|
								{
							 | 
						|
								protected:
							 | 
						|
								    ~FairMutexImplBase ();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class LOG4CPLUS_EXPORT FairMutex
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    FairMutex ();
							 | 
						|
								    ~FairMutex ();
							 | 
						|
								
							 | 
						|
								    void lock () const;
							 | 
						|
								    void unlock () const;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    FairMutexImplBase * mtx;
							 | 
						|
								
							 | 
						|
								    FairMutex (FairMutex const &);
							 | 
						|
								    FairMutex & operator = (FairMutex &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef SyncGuard<FairMutex> FairMutexGuard;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class ManualResetEventImplBase
							 | 
						|
								{
							 | 
						|
								protected:
							 | 
						|
								    ~ManualResetEventImplBase ();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class LOG4CPLUS_EXPORT ManualResetEvent
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    ManualResetEvent (bool = false);
							 | 
						|
								    ~ManualResetEvent ();
							 | 
						|
								
							 | 
						|
								    void signal () const;
							 | 
						|
								    void wait () const;
							 | 
						|
								    bool timed_wait (unsigned long msec) const;
							 | 
						|
								    void reset () const;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    ManualResetEventImplBase * ev;
							 | 
						|
								
							 | 
						|
								    ManualResetEvent (ManualResetEvent const &);
							 | 
						|
								    ManualResetEvent & operator = (ManualResetEvent const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class SharedMutexImplBase
							 | 
						|
								{
							 | 
						|
								protected:
							 | 
						|
								    ~SharedMutexImplBase ();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								class SyncGuardFunc
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    SyncGuardFunc (SP const &);
							 | 
						|
								    ~SyncGuardFunc ();
							 | 
						|
								
							 | 
						|
								    void lock ();
							 | 
						|
								    void unlock ();
							 | 
						|
								    void attach (SP const &);
							 | 
						|
								    void detach ();
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    SP const * sp;
							 | 
						|
								
							 | 
						|
								    SyncGuardFunc (SyncGuardFunc const &);
							 | 
						|
								    SyncGuardFunc & operator = (SyncGuardFunc const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class LOG4CPLUS_EXPORT SharedMutex
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    SharedMutex ();
							 | 
						|
								    ~SharedMutex ();
							 | 
						|
								
							 | 
						|
								    void rdlock () const;
							 | 
						|
								    void rdunlock () const;
							 | 
						|
								
							 | 
						|
								    void wrlock () const;
							 | 
						|
								    void wrunlock () const;
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    SharedMutexImplBase * sm;
							 | 
						|
								
							 | 
						|
								    SharedMutex (SharedMutex const &);
							 | 
						|
								    SharedMutex & operator = (SharedMutex const &);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef SyncGuardFunc<SharedMutex, &SharedMutex::rdlock,
							 | 
						|
								    &SharedMutex::rdunlock> SharedMutexReaderGuard;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								typedef SyncGuardFunc<SharedMutex, &SharedMutex::wrlock,
							 | 
						|
								    &SharedMutex::wrunlock> SharedMutexWriterGuard;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								SyncGuard<SP>::SyncGuard ()
							 | 
						|
								    : sp (0)
							 | 
						|
								{ }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								SyncGuard<SP>::SyncGuard (SP const & m)
							 | 
						|
								    : sp (&m)
							 | 
						|
								{
							 | 
						|
								    sp->lock ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								SyncGuard<SP>::~SyncGuard ()
							 | 
						|
								{
							 | 
						|
								    if (sp)
							 | 
						|
								        sp->unlock ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuard<SP>::lock ()
							 | 
						|
								{
							 | 
						|
								    sp->lock ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuard<SP>::unlock ()
							 | 
						|
								{
							 | 
						|
								    sp->unlock ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuard<SP>::attach (SP const & m)
							 | 
						|
								{
							 | 
						|
								    sp = &m;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuard<SP>::attach_and_lock (SP const & m)
							 | 
						|
								{
							 | 
						|
								    attach (m);
							 | 
						|
								    try
							 | 
						|
								    {
							 | 
						|
								        lock();
							 | 
						|
								    }
							 | 
						|
								    catch (...)
							 | 
						|
								    {
							 | 
						|
								        detach ();
							 | 
						|
								        throw;
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuard<SP>::detach ()
							 | 
						|
								{
							 | 
						|
								    sp = 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								//
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::SyncGuardFunc (SP const & m)
							 | 
						|
								    : sp (&m)
							 | 
						|
								{
							 | 
						|
								    (sp->*lock_func) ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::~SyncGuardFunc ()
							 | 
						|
								{
							 | 
						|
								    if (sp)
							 | 
						|
								        (sp->*unlock_func) ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::lock ()
							 | 
						|
								{
							 | 
						|
								    (sp->*lock_func) ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::unlock ()
							 | 
						|
								{
							 | 
						|
								    (sp->*unlock_func) ();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::attach (SP const & m)
							 | 
						|
								{
							 | 
						|
								    sp = &m;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename SP, void (SP:: * lock_func) () const,
							 | 
						|
								    void (SP:: * unlock_func) () const>
							 | 
						|
								inline
							 | 
						|
								void
							 | 
						|
								SyncGuardFunc<SP, lock_func, unlock_func>::detach ()
							 | 
						|
								{
							 | 
						|
								    sp = 0;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								} } // namespace log4cplus { namespace thread { 
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif // LOG4CPLUS_THREAD_SYNCPRIMS_H
							 |