Created
November 3, 2013 19:25
-
-
Save ArtemGr/7293793 to your computer and use it in GitHub Desktop.
Unbuffered Channel in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment