--- /dev/null
+## Process this file with automake to produce Makefile.in
+## ##################################################
+
+#INCLUDES
+
+## ##################################################
+
+threadincludedir = $(pkgincludedir)/thread
+
+threadinclude_HEADERS = \
+ MutexException.h \
+ Mutex.h \
+ MutexLock.h
+
+noinst_LTLIBRARIES = lib@PACKAGE@_thread.la
+
+## ##################################################
+
+lib@PACKAGE@_thread_la_SOURCES =\
+ Mutex.cc
+
+lib@PACKAGE@_thread_la_LDFLAGS = -pthread
+
+## ##################################################
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/thread/Mutex.cc
+ */
+#include <zypp/thread/Mutex.h>
+#include <zypp/thread/MutexException.h>
+
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////
+ namespace thread
+ { //////////////////////////////////////////////////////////////////
+
+ // -------------------------------------------------------------
+ Mutex::Mutex()
+ {
+ pthread_mutexattr_t attr;
+
+ int ret = pthread_mutexattr_init(&attr);
+ if( ret != 0)
+ {
+ ZYPP_THROW_ERRNO_MSG(zypp::thread::MutexException,
+ "Can't initialize mutex attributes");
+ }
+
+ ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ if( ret != 0)
+ {
+ ZYPP_THROW_ERRNO_MSG(MutexException,
+ "Can't set recursive mutex attribute");
+ }
+
+ ret = pthread_mutex_init(&m_mutex, &attr);
+ if( ret != 0)
+ {
+ ZYPP_THROW_ERRNO_MSG(MutexException,
+ "Can't initialize recursive mutex");
+ }
+ }
+
+ // -------------------------------------------------------------
+ Mutex::~Mutex()
+ {
+ if( pthread_mutex_destroy(&m_mutex) != 0 && errno == EBUSY)
+ {
+ // try to unlock and to destroy again...
+ if( pthread_mutex_unlock(&m_mutex) == 0)
+ {
+ pthread_mutex_destroy(&m_mutex);
+ }
+ /*
+ else
+ {
+ ZYPP_THROW_ERRNO_MSG(MutexException,
+ "Can't destroy mutex owned by another thread");
+ }
+ */
+ }
+ }
+
+ // -------------------------------------------------------------
+ void Mutex::lock()
+ {
+ if( pthread_mutex_lock(&m_mutex) != 0)
+ {
+ ZYPP_THROW_ERRNO_MSG(MutexException,
+ "Can't acquire the mutex lock");
+ }
+ }
+
+ // -------------------------------------------------------------
+ void Mutex::unlock()
+ {
+ if( pthread_mutex_unlock(&m_mutex) != 0)
+ {
+ ZYPP_THROW_ERRNO_MSG(MutexException,
+ "Can't release the mutex lock");
+ }
+ }
+
+ // -------------------------------------------------------------
+ bool Mutex::trylock()
+ {
+ return (pthread_mutex_trylock(&m_mutex) == 0);
+ }
+
+
+ //////////////////////////////////////////////////////////////////
+ } // namespace thread
+ ////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/thread/Mutex.h
+ */
+#ifndef ZYPP_THREAD_MUTEX_H
+#define ZYPP_THREAD_MUTEX_H
+
+#include <zypp/base/NonCopyable.h>
+#include <zypp/thread/MutexException.h>
+#include <pthread.h>
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////
+ namespace thread
+ { //////////////////////////////////////////////////////////////////
+
+
+ typedef pthread_mutex_t RecursiveMutex_t;
+
+
+ ////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Mutex
+ //
+ /** A recursive Mutex.
+ */
+ class Mutex: public zypp::base::NonCopyable
+ {
+ public:
+ /** Create a new recursive Mutex object.
+ * \throws MutexException on initialization failure.
+ */
+ Mutex();
+
+ /** Destroys this Mutex object.
+ */
+ ~Mutex();
+
+ /** Acquire ownership of this Mutex object.
+ * This call will block if another thread has ownership of
+ * this Mutex. When it returns, the current thread is the
+ * owner of this Mutex object.
+ *
+ * In the same thread, this recursive mutex can be acquired
+ * multiple times.
+ *
+ * \throws MutexException if the maximum number of recursive
+ * locks for mutex has been exceeded.
+ */
+ void lock();
+
+ /** Release ownership of this Mutex object.
+ * If another thread is waiting to acquire the ownership of
+ * this mutex it will stop blocking and acquire ownership
+ * when this call returns.
+ *
+ * \throws MutexException if the current thread does not
+ * own the mutex.
+ */
+ void unlock();
+
+ /** Try to acquire ownership of this Mutex object.
+ * This call will return false if another thread has ownership
+ * of this Mutex or the maximum number of recursive locks for
+ * mutex has been exceeded.
+ * When it returns true, the current thread is the owner of
+ * this Mutex object.
+ *
+ * \return true, if ownership was acquired.
+ */
+ bool trylock();
+
+ private:
+ RecursiveMutex_t m_mutex;
+ };
+
+
+ //////////////////////////////////////////////////////////////////
+ } // namespace thread
+ ////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_THREAD_MUTEX_H
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/thread/MutexException.h
+ *
+*/
+#ifndef ZYPP_THREAD_MUTEXEXCEPTION_H
+#define ZYPP_THREAD_MUTEXEXCEPTION_H
+
+#include <zypp/base/Exception.h>
+
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////
+ namespace thread
+ { //////////////////////////////////////////////////////////////////
+
+
+ ////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : MutexException
+ //
+ /** Exception type thrown on mutex errors.
+ */
+ class MutexException: public zypp::Exception
+ {
+ public:
+ MutexException()
+ : zypp::Exception( ::zypp::Exception::strErrno(errno))
+ {}
+
+ MutexException(const std::string &msg)
+ : zypp::Exception( msg)
+ {}
+
+ virtual ~MutexException() throw()
+ {}
+ };
+
+
+ //////////////////////////////////////////////////////////////////
+ } // namespace thread
+ ////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_THREAD_MUTEXEXCEPTION_H
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/thread/MutexLock.h
+ *
+*/
+#ifndef ZYPP_THREAD_MUTEXLOCK_H
+#define ZYPP_THREAD_MUTEXLOCK_H
+
+#include <zypp/thread/Mutex.h>
+#include <cassert>
+
+
+//////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////
+ namespace thread
+ { //////////////////////////////////////////////////////////////////
+
+
+ // -------------------------------------------------------------
+ class MutexLock
+ {
+ public:
+ explicit MutexLock(Mutex &mutex, bool init_locked=true)
+ : m_mutex(&mutex)
+ , m_locked(false)
+ {
+ if(init_locked)
+ lock();
+ }
+
+ MutexLock(const MutexLock &ref)
+ : m_mutex( ref.m_mutex)
+ , m_locked(ref.m_locked)
+ {
+ ref.m_locked = false;
+ }
+
+ ~MutexLock()
+ {
+ try
+ {
+ if( m_locked)
+ unlock();
+ }
+ catch( ... )
+ {
+ // don't let exceptions escape
+ }
+ }
+
+ void lock()
+ {
+ assert(m_locked == false);
+ m_mutex->lock();
+ m_locked = true;
+ }
+
+ void unlock()
+ {
+ assert(m_locked == true);
+ m_mutex->unlock();
+ m_locked = false;
+ }
+
+ bool trylock()
+ {
+ assert(m_locked == false);
+ m_locked = m_mutex->trylock();
+ return m_locked;
+ }
+
+ bool locked()
+ {
+ return m_locked;
+ }
+
+ private:
+ Mutex *m_mutex;
+ mutable bool m_locked;
+ //friend class Condition;
+ };
+
+
+ //////////////////////////////////////////////////////////////////
+ } // namespace thread
+ ////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////
+} // namespace zypp
+//////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_THREAD_MUTEXLOCK_H
+/*
+** vim: set ts=2 sts=2 sw=2 ai et:
+*/