]> git.cworth.org Git - apitrace/commitdiff
Condition variable abstraction.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Mon, 22 Oct 2012 18:51:00 +0000 (19:51 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Mon, 22 Oct 2012 18:51:00 +0000 (19:51 +0100)
common/os_thread.hpp
common/os_workqueue.hpp
common/workqueue_posix.cpp

index c4bc130d4693b7d9bb201da8675543acdcd4659d..e5eb19d3604c8dd61c47e5ccd22c4b57f1f72e28 100644 (file)
@@ -139,6 +139,98 @@ namespace os {
     };
 
 
+    /**
+     * Same interface as std::unique_lock;
+     */
+    template< class Mutex >
+    class unique_lock
+    {
+    public:
+        typedef Mutex mutex_type;
+
+        inline explicit
+        unique_lock(mutex_type & mutex) :
+            _mutex(&mutex)
+        {
+            _mutex->lock();
+        }
+
+        inline
+        ~unique_lock() {
+            _mutex->unlock();
+        }
+
+        inline void
+        lock() {
+            _mutex->lock();
+        }
+
+        inline void
+        unlock() {
+            _mutex->unlock();
+        }
+
+        mutex_type *
+        mutex() const {
+            return _mutex;
+        }
+
+    protected:
+        mutex_type *_mutex;
+    };
+
+
+    /**
+     * Same interface as std::condition_variable
+     */
+    class condition_variable
+    {
+    public:
+#ifdef _WIN32
+        /* FIXME */
+#else
+        typedef pthread_cond_t native_handle_type;
+#endif
+
+        condition_variable() {
+#ifdef _WIN32
+            /* FIXME */
+#else
+            pthread_cond_init(&_native_handle, NULL);
+#endif
+        }
+
+        ~condition_variable() {
+#ifdef _WIN32
+            /* FIXME */
+#else
+            pthread_cond_destroy(&_native_handle);
+#endif
+        }
+
+        inline void
+        signal(void) {
+#ifdef _WIN32
+            /* FIXME */
+#else
+            pthread_cond_signal(&_native_handle);
+#endif
+        }
+
+        inline void
+        wait(unique_lock<mutex> & lock) {
+#ifdef _WIN32
+            /* FIXME */
+#else
+            pthread_cond_wait(&_native_handle, &lock.mutex()->native_handle());
+#endif
+        }
+
+    protected:
+        native_handle_type _native_handle;
+    };
+
+
     /**
      * Same interface as boost::thread_specific_ptr.
      */
index e41d8b27db3ef547ceb14502ddd9ecb0c4dac33d..1c6798c1ac3f08ce2ee7ca11a5517e30f427230b 100644 (file)
@@ -28,10 +28,10 @@ class WorkQueue {
 
        bool busy;
        bool exit_workqueue;
-       pthread_cond_t wake_cond;
-       pthread_cond_t complete_cond;
+       os::condition_variable wake_cond;
+       os::condition_variable complete_cond;
 
-       os::mutex lock;
+       os::mutex mutex;
 
        void wake_up_thread(void);
        void thread_entry(void);
index 9b02d6c0c2fc5683638280c99ac43182ae57ea73..f46bbd977bd20ee87e5e273539df8512a38ac41d 100644 (file)
@@ -12,13 +12,13 @@ namespace os
  */
 int WorkQueue::run_tasks(void)
 {
-    lock.lock();
+    os::unique_lock<os::mutex> lock(mutex);
 
-    while (work_queue.empty() && !exit_workqueue)
-        pthread_cond_wait(&wake_cond, &lock.native_handle());
+    while (work_queue.empty() && !exit_workqueue) {
+        wake_cond.wait(lock);
+    }
 
     if (exit_workqueue) {
-        lock.unlock();
         return -1;
     }
 
@@ -41,9 +41,7 @@ int WorkQueue::run_tasks(void)
     lock.lock();
 
     busy = false;
-    pthread_cond_signal(&complete_cond);
-
-    lock.unlock();
+    complete_cond.signal();
 
     return 0;
 }
@@ -51,23 +49,23 @@ int WorkQueue::run_tasks(void)
 /* Must be called with WorkQueue::lock held */
 void WorkQueue::wake_up_thread(void)
 {
-    pthread_cond_signal(&wake_cond);
+    wake_cond.signal();
 }
 
 void WorkQueue::queue_work(WorkQueueWork *task)
 {
-    lock.lock();
+    mutex.lock();
     work_queue.push(task);
     wake_up_thread();
-    lock.unlock();
+    mutex.unlock();
 }
 
 void WorkQueue::flush(void)
 {
-    lock.lock();
-    while (!work_queue.empty() || busy)
-        pthread_cond_wait(&complete_cond, &lock.native_handle());
-    lock.unlock();
+    os::unique_lock<os::mutex> lock(mutex);
+    while (!work_queue.empty() || busy) {
+        complete_cond.wait(lock);
+    }
 }
 
 void WorkQueue::thread_entry(void)
@@ -81,10 +79,10 @@ void WorkQueue::thread_entry(void)
 
 void WorkQueue::destroy(void)
 {
-    lock.lock();
+    mutex.lock();
     exit_workqueue = true;
     wake_up_thread();
-    lock.unlock();
+    mutex.unlock();
 }
 
 extern "C"
@@ -102,8 +100,6 @@ WorkQueue::WorkQueue(void) :
 {
     int err;
 
-    pthread_cond_init(&wake_cond, NULL);
-    pthread_cond_init(&complete_cond, NULL);
     err = pthread_create(&handle, NULL, WorkQueue__entry_thunk, this);
     assert(!err);
 }