diff options
author | Thomas Winget <tewinget@gmail.com> | 2014-10-13 18:52:45 -0400 |
---|---|---|
committer | warptangent <warptangent@inbox.com> | 2015-01-04 18:41:44 -0800 |
commit | 90d6f8bf62bca97dc911b30505252becd8ef7520 (patch) | |
tree | b87d425251db5171dd66f7a83e8f009ead72b176 /external/glim/channel.hpp | |
parent | update new blockchain to build with new changes (diff) | |
download | monero-90d6f8bf62bca97dc911b30505252becd8ef7520.tar.xz |
Adding libglim as an external library
libglim is an Apache-licensed C++ wrapper for lmdb, and rather than
rolling our own it seems prudent to use it.
Note: lmdb is not included in it, and unless something happens as did
with libunbound, should be installed via each OS' package manager or
equivalent.
Diffstat (limited to '')
-rw-r--r-- | external/glim/channel.hpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/external/glim/channel.hpp b/external/glim/channel.hpp new file mode 100644 index 000000000..e5ca23bdf --- /dev/null +++ b/external/glim/channel.hpp @@ -0,0 +1,40 @@ +#ifndef _GLIM_CHANNEL_INCLUDED +#define _GLIM_CHANNEL_INCLUDED + +#include <atomic> +#include <mutex> +#include <thread> + +namespace glim { + +/// Unbuffered channel. +/// Optimized for a single value (busy-waits on a second one). +template <typename V> +struct Channel { + V _v; + std::mutex _mutex; // Locked when there is no value. + std::atomic_int_fast8_t _state; enum State {EMPTY = 0, WRITING = 1, FULL = 2}; + Channel(): _state (EMPTY) {_mutex.lock();} + // Waits until the Channel is empty then stores the value. + template <typename VA> void send (VA&& v) { + for (;;) { + int_fast8_t expectEmpty = EMPTY; if (_state.compare_exchange_weak (expectEmpty, WRITING)) break; + std::this_thread::sleep_for (std::chrono::milliseconds (20)); + } + try {_v = std::forward<V> (v);} catch (...) {_state = EMPTY; throw;} + _state = FULL; + _mutex.unlock(); // Allows the reader to proceed. + } + // Waits untill there is a value to receive. + V receive() { + _mutex.lock(); // Wait. + V tmp = std::move (_v); + assert (_state == FULL); + _state = EMPTY; + return tmp; + } +}; + +} // namespace glim + +#endif |