2 * Copyright (C) 2013 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #ifndef INCL_THREAD_SUPPORT
21 # define INCL_THREAD_SUPPORT
30 # define GLIB_CHECK_VERSION(major, minor, revision) 0
33 #include <boost/shared_ptr.hpp>
35 #include <syncevo/declarations.h>
38 // The revised threading API we use below was introduced in glib 2.3.2
39 // The fallback for older glib is to not offer thread support.
40 // The classes are still defined, they just don't do anything.
41 #if GLIB_CHECK_VERSION(2, 32, 0)
42 # define HAVE_THREAD_SUPPORT
45 * Core building block for mutices.
47 template<class M, void (*_lock)(M *), void (*_unlock)(M *)> class MutexTemplate
54 * Created when locking the mutex. When the last copy of it
55 * gets destroyed, the mutex gets unlocked again.
57 class Guard : private boost::shared_ptr<M>
59 Guard(M *mutex) throw () :
60 boost::shared_ptr<M>(mutex, _unlock)
62 friend class MutexTemplate;
70 boost::shared_ptr<M>::reset();
75 * Lock the mutex and return a handle that'll automatically
76 * unlock the mutex when the last copy gets destroyed.
81 return Guard(&m_mutex);
84 M *get() { return &m_mutex; }
85 operator M * () { return &m_mutex; }
89 * Initializes a mutex which was allocated dynamically
90 * on the heap or stack and frees allocated resources
91 * when done. It's an error to free a locked mutex.
93 template<class M, void (*_lock)(M *), void (*_unlock)(M *), void (*_init)(M *), void (*_clear)(M *)> class DynMutexTemplate :
94 public MutexTemplate<M, _lock, _unlock>
99 _init(MutexTemplate<M, _lock, _unlock>::get());
103 _clear(MutexTemplate<M, _lock, _unlock>::get());
107 typedef MutexTemplate<GMutex, g_mutex_lock, g_mutex_unlock> Mutex;
108 typedef DynMutexTemplate<GMutex, g_mutex_lock, g_mutex_unlock, g_mutex_init, g_mutex_clear> DynMutex;
109 typedef MutexTemplate<GRecMutex, g_rec_mutex_lock, g_rec_mutex_unlock> RecMutex;
110 typedef DynMutexTemplate<GRecMutex, g_rec_mutex_lock, g_rec_mutex_unlock, g_rec_mutex_init, g_rec_mutex_clear> DynRecMutex;
117 Cond() { g_cond_init(&m_cond); }
118 ~Cond() { g_cond_clear(&m_cond); }
120 void signal() { g_cond_signal(&m_cond); }
121 template<class M> void wait(M &m) { g_cond_wait(&m_cond, m); }
126 # undef HAVE_THREAD_SUPPORT
129 * Fallback just to get code compiled.
137 void unlock() throw() {}
140 Guard lock() throw() { return Guard(); }
143 typedef DummyMutex Mutex;
144 typedef DummyMutex DynMutex;
145 typedef DummyMutex RecMutex;
146 typedef DummyMutex RecDynMutex;
152 template<class M> void wait(M &m) {}
159 #endif // INCL_THREAD_SUPPORT