%PDF- %PDF-
| Direktori : /proc/thread-self/root/backups/router/usr/local/include/log4cplus/thread/ |
| Current File : //proc/thread-self/root/backups/router/usr/local/include/log4cplus/thread/syncprims.h |
// -*- C++ -*-
// Copyright (C) 2010-2017, 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
#include <mutex>
#include <condition_variable>
namespace log4cplus { namespace thread {
template <typename SyncPrim>
class SyncGuard
{
public:
SyncGuard ();
SyncGuard (SyncPrim const &);
~SyncGuard ();
SyncGuard (SyncGuard const &) = delete;
SyncGuard & operator = (SyncGuard const &) = delete;
void lock ();
void unlock ();
void attach (SyncPrim const &);
void attach_and_lock (SyncPrim const &);
void detach ();
private:
SyncPrim const * sp;
};
class LOG4CPLUS_EXPORT SimpleMutex
{
public:
SimpleMutex ();
~SimpleMutex ();
SimpleMutex (SimpleMutex const &) = delete;
SimpleMutex & operator = (SimpleMutex const &) = delete;
void lock () const;
bool try_lock () const;
void unlock () const;
private:
LOG4CPLUS_THREADED (mutable std::mutex mtx;)
};
typedef SyncGuard<SimpleMutex> SimpleMutexGuard;
class LOG4CPLUS_EXPORT Mutex
{
public:
Mutex ();
~Mutex ();
Mutex (Mutex const &) = delete;
Mutex & operator = (Mutex const &) = delete;
void lock () const;
void unlock () const;
private:
LOG4CPLUS_THREADED (mutable std::recursive_mutex mtx;)
};
typedef SyncGuard<Mutex> MutexGuard;
class LOG4CPLUS_EXPORT Semaphore
{
public:
Semaphore (unsigned max, unsigned initial);
~Semaphore ();
Semaphore (Semaphore const &) = delete;
Semaphore & operator = (Semaphore const &) = delete;
void lock () const;
void unlock () const;
private:
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
mutable std::mutex mtx;
mutable std::condition_variable cv;
mutable unsigned maximum;
mutable unsigned val;
#endif
};
typedef SyncGuard<Semaphore> SemaphoreGuard;
class LOG4CPLUS_EXPORT ManualResetEvent
{
public:
explicit ManualResetEvent (bool = false);
~ManualResetEvent ();
ManualResetEvent (ManualResetEvent const &) = delete;
ManualResetEvent & operator = (ManualResetEvent const &) = delete;
void signal () const;
void wait () const;
bool timed_wait (unsigned long msec) const;
void reset () const;
private:
#if ! defined (LOG4CPLUS_SINGLE_THREADED)
mutable std::mutex mtx;
mutable std::condition_variable cv;
mutable bool signaled;
mutable unsigned sigcount;
#endif
};
class SharedMutexImplBase
{
protected:
~SharedMutexImplBase ();
};
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
class SyncGuardFunc
{
public:
SyncGuardFunc (SyncPrim const &);
~SyncGuardFunc ();
void lock ();
void unlock ();
void attach (SyncPrim const &);
void detach ();
private:
SyncPrim 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 SyncPrim>
inline
SyncGuard<SyncPrim>::SyncGuard ()
: sp (0)
{ }
template <typename SyncPrim>
inline
SyncGuard<SyncPrim>::SyncGuard (SyncPrim const & m)
: sp (&m)
{
sp->lock ();
}
template <typename SyncPrim>
inline
SyncGuard<SyncPrim>::~SyncGuard ()
{
if (sp)
sp->unlock ();
}
template <typename SyncPrim>
inline
void
SyncGuard<SyncPrim>::lock ()
{
sp->lock ();
}
template <typename SyncPrim>
inline
void
SyncGuard<SyncPrim>::unlock ()
{
sp->unlock ();
}
template <typename SyncPrim>
inline
void
SyncGuard<SyncPrim>::attach (SyncPrim const & m)
{
sp = &m;
}
template <typename SyncPrim>
inline
void
SyncGuard<SyncPrim>::attach_and_lock (SyncPrim const & m)
{
attach (m);
try
{
lock();
}
catch (...)
{
detach ();
throw;
}
}
template <typename SyncPrim>
inline
void
SyncGuard<SyncPrim>::detach ()
{
sp = 0;
}
//
//
//
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::SyncGuardFunc (SyncPrim const & m)
: sp (&m)
{
(sp->*lock_func) ();
}
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::~SyncGuardFunc ()
{
if (sp)
(sp->*unlock_func) ();
}
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
void
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::lock ()
{
(sp->*lock_func) ();
}
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
void
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::unlock ()
{
(sp->*unlock_func) ();
}
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
void
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::attach (SyncPrim const & m)
{
sp = &m;
}
template <typename SyncPrim, void (SyncPrim:: * lock_func) () const,
void (SyncPrim:: * unlock_func) () const>
inline
void
SyncGuardFunc<SyncPrim, lock_func, unlock_func>::detach ()
{
sp = 0;
}
} } // namespace log4cplus { namespace thread {
#endif // LOG4CPLUS_THREAD_SYNCPRIMS_H