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

// -*- C++ -*-
// Copyright (C) 2010-2013, 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