[beast: 16/20] SFI: add and use AsyncBlockingQueue from Rapicorn
- From: Tim Janik <timj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [beast: 16/20] SFI: add and use AsyncBlockingQueue from Rapicorn
- Date: Sun, 24 Sep 2017 00:20:59 +0000 (UTC)
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]