From 82311849bbba61d0f1c49bd83abb9ffd52033bf2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 22 Oct 2012 19:14:27 +0100 Subject: [PATCH] Add and use os::mutex. --- common/os_thread.hpp | 57 +++++++++++++++++++++++++++++++++++--- common/os_workqueue.hpp | 8 ++++-- common/workqueue_posix.cpp | 27 +++++++++--------- common/workqueue_win32.cpp | 1 - 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/common/os_thread.hpp b/common/os_thread.hpp index fe7faaa..c4bc130 100644 --- a/common/os_thread.hpp +++ b/common/os_thread.hpp @@ -42,7 +42,10 @@ namespace os { - class recursive_mutex + /** + * Base class for mutex and recursive_mutex. + */ + class _base_mutex { public: #ifdef _WIN32 @@ -51,7 +54,7 @@ namespace os { typedef pthread_mutex_t native_handle_type; #endif - recursive_mutex(void) { + _base_mutex(void) { #ifdef _WIN32 InitializeCriticalSection(&_native_handle); #else @@ -63,7 +66,7 @@ namespace os { #endif } - ~recursive_mutex() { + ~_base_mutex() { #ifdef _WIN32 DeleteCriticalSection(&_native_handle); #else @@ -89,11 +92,56 @@ namespace os { #endif } - private: + native_handle_type & native_handle() { + return _native_handle; + } + + protected: native_handle_type _native_handle; }; + /** + * Same interface as std::mutex. + */ + class mutex : public _base_mutex + { + public: + inline + mutex(void) { +#ifdef _WIN32 + InitializeCriticalSection(&_native_handle); +#else + pthread_mutex_init(&_native_handle, NULL); +#endif + } + }; + + + /** + * Same interface as std::recursive_mutex. + */ + class recursive_mutex : public _base_mutex + { + public: + inline + recursive_mutex(void) { +#ifdef _WIN32 + InitializeCriticalSection(&_native_handle); +#else + 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); +#endif + } + }; + + + /** + * Same interface as boost::thread_specific_ptr. + */ template class thread_specific_ptr { @@ -158,6 +206,7 @@ namespace os { } }; + } /* namespace os */ #endif /* _OS_THREAD_HPP_ */ diff --git a/common/os_workqueue.hpp b/common/os_workqueue.hpp index e6b77d4..e41d8b2 100644 --- a/common/os_workqueue.hpp +++ b/common/os_workqueue.hpp @@ -3,8 +3,10 @@ #include -namespace os -{ +#include "os_thread.hpp" + +namespace os { + class WorkQueue; @@ -29,7 +31,7 @@ class WorkQueue { pthread_cond_t wake_cond; pthread_cond_t complete_cond; - pthread_mutex_t lock; + os::mutex lock; void wake_up_thread(void); void thread_entry(void); diff --git a/common/workqueue_posix.cpp b/common/workqueue_posix.cpp index dbcb82e..9b02d6c 100644 --- a/common/workqueue_posix.cpp +++ b/common/workqueue_posix.cpp @@ -12,13 +12,13 @@ namespace os */ int WorkQueue::run_tasks(void) { - pthread_mutex_lock(&lock); + lock.lock(); while (work_queue.empty() && !exit_workqueue) - pthread_cond_wait(&wake_cond, &lock); + pthread_cond_wait(&wake_cond, &lock.native_handle()); if (exit_workqueue) { - pthread_mutex_unlock(&lock); + lock.unlock(); return -1; } @@ -26,7 +26,7 @@ int WorkQueue::run_tasks(void) std::swap(work_queue, batch); busy = true; - pthread_mutex_unlock(&lock); + lock.unlock(); assert(!batch.empty()); while (!batch.empty()) { @@ -38,12 +38,12 @@ int WorkQueue::run_tasks(void) delete task; } - pthread_mutex_lock(&lock); + lock.lock(); busy = false; pthread_cond_signal(&complete_cond); - pthread_mutex_unlock(&lock); + lock.unlock(); return 0; } @@ -56,18 +56,18 @@ void WorkQueue::wake_up_thread(void) void WorkQueue::queue_work(WorkQueueWork *task) { - pthread_mutex_lock(&lock); + lock.lock(); work_queue.push(task); wake_up_thread(); - pthread_mutex_unlock(&lock); + lock.unlock(); } void WorkQueue::flush(void) { - pthread_mutex_lock(&lock); + lock.lock(); while (!work_queue.empty() || busy) - pthread_cond_wait(&complete_cond, &lock); - pthread_mutex_unlock(&lock); + pthread_cond_wait(&complete_cond, &lock.native_handle()); + lock.unlock(); } void WorkQueue::thread_entry(void) @@ -81,10 +81,10 @@ void WorkQueue::thread_entry(void) void WorkQueue::destroy(void) { - pthread_mutex_lock(&lock); + lock.lock(); exit_workqueue = true; wake_up_thread(); - pthread_mutex_unlock(&lock); + lock.unlock(); } extern "C" @@ -104,7 +104,6 @@ WorkQueue::WorkQueue(void) : pthread_cond_init(&wake_cond, NULL); pthread_cond_init(&complete_cond, NULL); - pthread_mutex_init(&lock, NULL); err = pthread_create(&handle, NULL, WorkQueue__entry_thunk, this); assert(!err); } diff --git a/common/workqueue_win32.cpp b/common/workqueue_win32.cpp index cec6693..3c1b9cd 100644 --- a/common/workqueue_win32.cpp +++ b/common/workqueue_win32.cpp @@ -1,4 +1,3 @@ -#include #include #include -- 2.43.0