[beast: 16/20] SFI: add and use AsyncBlockingQueue from Rapicorn



commit ae58c928ffbfa09c523d83567d6271de6fbe45b7
Author: Tim Janik <timj gnu org>
Date:   Sun Sep 17 15:03:52 2017 +0200

    SFI: add and use AsyncBlockingQueue from Rapicorn
    
    Import is based on Rapicorn commit id:
        bf228016cba3f6d252ee2cc38e1ed32607f37bf0
    
    Signed-off-by: Tim Janik <timj gnu org>

 sfi/bcore.hh |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 54 insertions(+), 1 deletions(-)
---
diff --git a/sfi/bcore.hh b/sfi/bcore.hh
index 63e2113..697e3bc 100644
--- a/sfi/bcore.hh
+++ b/sfi/bcore.hh
@@ -32,7 +32,6 @@ using   Rapicorn::void_t;
 using   Rapicorn::Blob;
 using   Rapicorn::Res;
 using   Rapicorn::cpu_info;
-using   Rapicorn::AsyncBlockingQueue;
 
 // == Diagnostics ==
 template<class... Args> String      string_format        (const char *format, const Args &...args) 
BSE_PRINTF (1, 0);
@@ -296,6 +295,60 @@ public:
   Spinlock& operator=   (const Spinlock&) = delete;
 };
 
+// == AsyncBlockingQueue ==
+/** Asyncronous queue to push/pop values across thread boundaries.
+ * The AsyncBlockingQueue is a thread-safe asyncronous queue which blocks in pop() until data is provided 
through push() from any thread.
+ */
+template<class Value>
+class AsyncBlockingQueue {
+  std::mutex              mutex_;
+  std::condition_variable cond_;
+  std::list<Value>        list_;
+public:
+  void  push    (const Value &v);
+  Value pop     ();
+  bool  pending ();
+  void  swap    (std::list<Value> &list);
+};
+
+template<class Value> void
+AsyncBlockingQueue<Value>::push (const Value &v)
+{
+  std::lock_guard<std::mutex> locker (mutex_);
+  const bool notify = list_.empty();
+  list_.push_back (v);
+  if (BSE_UNLIKELY (notify))
+    cond_.notify_all();
+}
+
+template<class Value> Value
+AsyncBlockingQueue<Value>::pop ()
+{
+  std::unique_lock<std::mutex> locker (mutex_);
+  while (list_.empty())
+    cond_.wait (locker);
+  Value v = list_.front();
+  list_.pop_front();
+  return v;
+}
+
+template<class Value> bool
+AsyncBlockingQueue<Value>::pending()
+{
+  std::lock_guard<std::mutex> locker (mutex_);
+  return !list_.empty();
+}
+
+template<class Value> void
+AsyncBlockingQueue<Value>::swap (std::list<Value> &list)
+{
+  std::lock_guard<std::mutex> locker (mutex_);
+  const bool notify = list_.empty();
+  list_.swap (list);
+  if (notify && !list_.empty())
+    cond_.notify_all();
+}
+
 } // Bse
 
 #endif // __BSE_BCORE_HH__


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]