Module: check_mk
Branch: master
Commit: 941f54bc6f53c5c3b62ee99e5f214a028d533b76
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=941f54bc6f53c5…
Author: Sven Panne <sp(a)mathias-kettner.de>
Date: Wed Nov 18 10:19:08 2015 +0100
Added condition_variable. Polished mutex stuff a bit. More error checking.
---
livestatus/src/ConditionVariable.h | 90 ++++++++++++++++++++++++++++++++++++
livestatus/src/Mutex.h | 50 +++++++++-----------
2 files changed, 113 insertions(+), 27 deletions(-)
diff --git a/livestatus/src/ConditionVariable.h b/livestatus/src/ConditionVariable.h
new file mode 100644
index 0000000..ef4f9f1
--- /dev/null
+++ b/livestatus/src/ConditionVariable.h
@@ -0,0 +1,90 @@
+// +------------------------------------------------------------------+
+// | ____ _ _ __ __ _ __ |
+// | / ___| |__ ___ ___| | __ | \/ | |/ / |
+// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+// | | |___| | | | __/ (__| < | | | | . \ |
+// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+// | |
+// | Copyright Mathias Kettner 2014 mk(a)mathias-kettner.de |
+// +------------------------------------------------------------------+
+//
+// This file is part of Check_MK.
+// The official homepage is at
http://mathias-kettner.de/check_mk.
+//
+// check_mk is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation in version 2. check_mk is distributed
+// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
+// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+// PARTICULAR PURPOSE. See the GNU General Public License for more de-
+// ails. You should have received a copy of the GNU General Public
+// License along with GNU Make; see the file COPYING. If not, write
+// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+// Boston, MA 02110-1301 USA.
+
+#ifndef ConditionVariable_h
+#define ConditionVariable_h
+
+#include "config.h" // IWYU pragma: keep
+#include <pthread.h>
+#include <Mutex.h>
+
+// A more or less drop-in replacement for C++11's <condition_variable>
(partial)
+
+namespace mk {
+
+enum /* class */ cv_status { no_timeout, timeout };
+
+class condition_variable {
+public:
+ typedef pthread_cond_t *native_handle_type;
+
+ condition_variable() { check_status(pthread_cond_init(&_cond, 0)); }
+ ~condition_variable() { check_status(pthread_cond_destroy(&_cond)); }
+ void notify_one() { check_status(pthread_cond_signal(&_cond)); }
+ void notify_all() { check_status(pthread_cond_broadcast(&_cond)); }
+ void wait(unique_lock<mutex> &ul)
+ {
+ if (!ul) throw_system_error(EPERM);
+ check_status(pthread_cond_wait(&_cond, ul.mutex()->native_handle()));
+ }
+
+ template <typename Predicate>
+ void wait(unique_lock<mutex> &ul, Predicate p)
+ {
+ while (!p()) wait(ul);
+ }
+
+ // template<typename Rep, typename Period>
+ // cv_status wait_for(unique_lock<mutex>& ul,
+ // const chrono::duration<Rep, Period>& rtime);
+
+ // template<typename Rep, typename Period, typename Predicate>
+ // bool wait_for(unique_lock<mutex>& ul,
+ // const chrono::duration<Rep, Period>& rtime,
+ // Predicate p);
+
+ // template<typename Clock, typename Duration>
+ // cv_status wait_until(unique_lock<mutex>& lock,
+ // const chrono::time_point<Clock, Duration>& atime);
+
+ // template<typename Clock, typename Duration, typename Predicate>
+ // bool wait_until(unique_lock<mutex>& ul,
+ // const chrono::time_point<Clock, Duration>& atime,
+ // Predicate p);
+
+ native_handle_type native_handle() { return &_cond; }
+private:
+ condition_variable(const condition_variable &); // = delete
+ condition_variable &operator=(const condition_variable &); // = delete
+
+ pthread_cond_t _cond;
+};
+
+// void notify_all_at_thread_exit(condition_variable& cond,
+// unique_lock<mutex> ul);
+
+
+} // namespace mk
+
+#endif // ConditionVariable_h
diff --git a/livestatus/src/Mutex.h b/livestatus/src/Mutex.h
index 5085dd8..77c9632 100644
--- a/livestatus/src/Mutex.h
+++ b/livestatus/src/Mutex.h
@@ -44,29 +44,30 @@ inline void throw_system_error(int err)
}
+inline void check_status(int status)
+{
+ if (status != 0) throw_system_error(status);
+}
+
+
class mutex {
public:
typedef pthread_mutex_t *native_handle_type;
- mutex() { pthread_mutex_init(native_handle(), 0); }
- ~mutex() { check(pthread_mutex_destroy(native_handle())); }
- void lock() { check(pthread_mutex_lock(native_handle())); }
+ mutex() { check_status(pthread_mutex_init(native_handle(), 0)); }
+ ~mutex() { check_status(pthread_mutex_destroy(native_handle())); }
+ void lock() { check_status(pthread_mutex_lock(native_handle())); }
bool try_lock()
{
int status = pthread_mutex_trylock(native_handle());
- if (status != EBUSY) check(status);
+ if (status != EBUSY) check_status(status);
return status == 0;
}
- void unlock() { check(pthread_mutex_unlock(native_handle())); }
+ void unlock() { check_status(pthread_mutex_unlock(native_handle())); }
native_handle_type native_handle() { return &_mutex; }
private:
mutex(const mutex &); // = delete
mutex &operator=(const mutex &); // = delete
- static void check(int status)
- {
- if (status != 0) throw_system_error(status);
- }
-
pthread_mutex_t _mutex;
};
@@ -77,30 +78,25 @@ public:
recursive_mutex()
{
pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(native_handle(), &attr);
- pthread_mutexattr_destroy(&attr);
+ check_status(pthread_mutexattr_init(&attr));
+ check_status(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE));
+ check_status(pthread_mutex_init(native_handle(), &attr));
+ check_status(pthread_mutexattr_destroy(&attr));
}
- ~recursive_mutex() { check(pthread_mutex_destroy(native_handle())); }
- void lock() { check(pthread_mutex_lock(native_handle())); }
+ ~recursive_mutex() { check_status(pthread_mutex_destroy(native_handle())); }
+ void lock() { check_status(pthread_mutex_lock(native_handle())); }
bool try_lock()
{
int status = pthread_mutex_trylock(native_handle());
- if (status != EBUSY) check(status);
+ if (status != EBUSY) check_status(status);
return status == 0;
}
- void unlock() { check(pthread_mutex_unlock(native_handle())); }
+ void unlock() { check_status(pthread_mutex_unlock(native_handle())); }
native_handle_type native_handle() { return &_mutex; }
private:
recursive_mutex(const recursive_mutex &); // = delete;
recursive_mutex &operator=(const recursive_mutex &); // = delete;
- static void check(int status)
- {
- if (status != 0) throw_system_error(status);
- }
-
pthread_mutex_t _mutex;
};
@@ -162,12 +158,12 @@ public:
}
// template<typename Clock, typename Duration>
- // unique_lock(mutex_type& m, const chrono::time_point<Clock,
Duration>&
- // atime)
+ // unique_lock(mutex_type& m,
+ // const chrono::time_point<Clock, Duration>& atime);
// template<typename Rep, typename Period>
- // unique_lock(mutex_type& m, const chrono::duration<_Rep, _Period>&
- // __rtime)
+ // unique_lock(mutex_type& m,
+ // const chrono::duration<Rep, Period>& rtime);
~unique_lock()
{