1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 21:01:16 +02:00

Ensure that Callback is called only once

Also, make Callback movable but uncopyable.
This commit is contained in:
Eelco Dolstra 2019-09-03 12:51:35 +02:00
parent 8c4ea7a451
commit 7348653ff4
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
5 changed files with 36 additions and 17 deletions

View file

@ -445,21 +445,34 @@ string get(const T & map, const string & key, const string & def = "")
type T or an exception. (We abuse std::future<T> to pass the value or
exception.) */
template<typename T>
struct Callback
class Callback
{
std::function<void(std::future<T>)> fun;
std::atomic_flag done = ATOMIC_FLAG_INIT;
public:
Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
void operator()(T && t) const
Callback(Callback && callback) : fun(std::move(callback.fun))
{
auto prev = callback.done.test_and_set();
if (prev) done.test_and_set();
}
void operator()(T && t)
{
auto prev = done.test_and_set();
assert(!prev);
std::promise<T> promise;
promise.set_value(std::move(t));
fun(promise.get_future());
}
void rethrow(const std::exception_ptr & exc = std::current_exception()) const
void rethrow(const std::exception_ptr & exc = std::current_exception())
{
auto prev = done.test_and_set();
assert(!prev);
std::promise<T> promise;
promise.set_exception(exc);
fun(promise.get_future());