forked from lix-project/lix
Move Callback into its own header
This gets rid of the inclusion of <future> in util.hh, cutting compilation time by ~20s (CPU time). Issue #4045.
This commit is contained in:
parent
e8e1d420f3
commit
d51ba43047
|
@ -11,6 +11,7 @@
|
||||||
#include "nar-accessor.hh"
|
#include "nar-accessor.hh"
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "daemon.hh"
|
#include "daemon.hh"
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "topo-sort.hh"
|
#include "topo-sort.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "s3.hh"
|
#include "s3.hh"
|
||||||
#include "compression.hh"
|
#include "compression.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#ifdef ENABLE_S3
|
#ifdef ENABLE_S3
|
||||||
#include <aws/core/client/ClientConfiguration.h>
|
#include <aws/core/client/ClientConfiguration.h>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "filetransfer.hh"
|
#include "filetransfer.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "nar-info-disk-cache.hh"
|
#include "nar-info-disk-cache.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "ssh.hh"
|
#include "ssh.hh"
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "derivations.hh"
|
#include "derivations.hh"
|
||||||
#include "nar-info.hh"
|
#include "nar-info.hh"
|
||||||
#include "references.hh"
|
#include "references.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "thread-pool.hh"
|
#include "thread-pool.hh"
|
||||||
#include "topo-sort.hh"
|
#include "topo-sort.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "pool.hh"
|
#include "pool.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "logging.hh"
|
#include "logging.hh"
|
||||||
|
#include "callback.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
#include "json.hh"
|
#include "json.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
|
#include "callback.hh"
|
||||||
#include <future>
|
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
46
src/libutil/callback.hh
Normal file
46
src/libutil/callback.hh
Normal file
|
@ -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());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -17,7 +17,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <future>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
|
#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>
|
template<typename T>
|
||||||
class 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) { }
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Start a thread that handles various signals. Also block those signals
|
/* Start a thread that handles various signals. Also block those signals
|
||||||
|
|
Loading…
Reference in a new issue