diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 34f844a180bf546c5b3ac0abb20c44b62ec53435..ebc0bd6a4e493827939e25df51c7985d021647ce 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -11,6 +11,7 @@ #include "nar-accessor.hh" #include "json.hh" #include "thread-pool.hh" +#include "callback.hh" #include <chrono> #include <future> diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 6e55f83d5fc8bf72542b522a92a8b081e0ecf485..0b51d90eae3c0c4444277f84c22aa8c8f459ada2 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -17,6 +17,7 @@ #include "daemon.hh" #include "worker-protocol.hh" #include "topo-sort.hh" +#include "callback.hh" #include <algorithm> #include <iostream> diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index 128832e605bfd2b75962a36db385b13f83b6498b..49641c2acc04868caf173b5ab04c56e81b24d5af 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -1,4 +1,5 @@ #include "store-api.hh" +#include "callback.hh" namespace nix { diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 4149f81550d6e2f996fafa05bb490e444e8fd880..6241b5e005b573ceed1233149ca4b7536be7ee10 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -5,6 +5,7 @@ #include "s3.hh" #include "compression.hh" #include "finally.hh" +#include "callback.hh" #ifdef ENABLE_S3 #include <aws/core/client/ClientConfiguration.h> diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index f4ab15a10983d5e372a6e817234b858622213b26..86be7c006cef8cc97446759331eb5a3389fe14fa 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -2,6 +2,7 @@ #include "filetransfer.hh" #include "globals.hh" #include "nar-info-disk-cache.hh" +#include "callback.hh" namespace nix { diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index e9478c1d50e2a4295c2ca8aeeefc02190f848c89..5af75669afc3bd492524b579173f13fefe6521f2 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -6,6 +6,7 @@ #include "worker-protocol.hh" #include "ssh.hh" #include "derivations.hh" +#include "callback.hh" namespace nix { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index c618203f07ed263306f2ae63e2599cd75d1d63ca..94ff34cb8e7b81d723c1d97e06f9e5dc59f2bb1b 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -6,6 +6,7 @@ #include "derivations.hh" #include "nar-info.hh" #include "references.hh" +#include "callback.hh" #include <iostream> #include <algorithm> diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index da39816962163c6ac406e02a459cfaf9eb6a3cdc..ad4dccef995e25cefce4a79e37e04d8b2e296943 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -5,7 +5,7 @@ #include "store-api.hh" #include "thread-pool.hh" #include "topo-sort.hh" - +#include "callback.hh" namespace nix { diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index e92b94975de3d304c1509b41c0dbca2a30b6d93c..27535f1d04a403478e22cb34f49448e749b7f80d 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -10,6 +10,7 @@ #include "pool.hh" #include "finally.hh" #include "logging.hh" +#include "callback.hh" #include <sys/types.h> #include <sys/stat.h> diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 2d5077ed033929a769e906e713e1804a6367ea43..1bbc74db80d91c0e420fff90e5d71385f03ce246 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -8,9 +8,7 @@ #include "json.hh" #include "url.hh" #include "archive.hh" - -#include <future> - +#include "callback.hh" namespace nix { diff --git a/src/libutil/callback.hh b/src/libutil/callback.hh new file mode 100644 index 0000000000000000000000000000000000000000..ef31794bee30dd2deb9789436bef529cb38c4a90 --- /dev/null +++ b/src/libutil/callback.hh @@ -0,0 +1,46 @@ +#pragma once + +#include <future> +#include <functional> + +namespace nix { + +/* A callback is a wrapper around a lambda that accepts a valid of + type T or an exception. (We abuse std::future<T> to pass the value or + exception.) */ +template<typename T> +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) { } + + 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) noexcept + { + 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()) noexcept + { + auto prev = done.test_and_set(); + assert(!prev); + std::promise<T> promise; + promise.set_exception(exc); + fun(promise.get_future()); + } +}; + +} diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 082e263757971fd77d8ada38b5a0c92a8cc962ed..91e0a15436f38b98dff3a259ce25c065a262e498 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -17,7 +17,6 @@ #include <map> #include <sstream> #include <optional> -#include <future> #include <iterator> #ifndef HAVE_STRUCT_DIRENT_D_TYPE @@ -480,43 +479,8 @@ std::optional<typename T::mapped_type> get(const T & map, const typename T::key_ } -/* A callback is a wrapper around a lambda that accepts a valid of - type T or an exception. (We abuse std::future<T> to pass the value or - exception.) */ template<typename T> -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) { } - - 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) noexcept - { - 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()) noexcept - { - auto prev = done.test_and_set(); - assert(!prev); - std::promise<T> promise; - promise.set_exception(exc); - fun(promise.get_future()); - } -}; +class Callback; /* Start a thread that handles various signals. Also block those signals