Skip to content

Commit

Permalink
Move Callback into its own header
Browse files Browse the repository at this point in the history
This gets rid of the inclusion of <future> in util.hh, cutting
compilation time by ~20s (CPU time).

Issue #4045.
  • Loading branch information
edolstra committed Sep 21, 2020
1 parent e8e1d42 commit d51ba43
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/libstore/binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "nar-accessor.hh"
#include "json.hh"
#include "thread-pool.hh"
#include "callback.hh"

#include <chrono>
#include <future>
Expand Down
1 change: 1 addition & 0 deletions src/libstore/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "daemon.hh"
#include "worker-protocol.hh"
#include "topo-sort.hh"
#include "callback.hh"

#include <algorithm>
#include <iostream>
Expand Down
1 change: 1 addition & 0 deletions src/libstore/dummy-store.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "store-api.hh"
#include "callback.hh"

namespace nix {

Expand Down
1 change: 1 addition & 0 deletions src/libstore/filetransfer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions src/libstore/http-binary-cache-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "filetransfer.hh"
#include "globals.hh"
#include "nar-info-disk-cache.hh"
#include "callback.hh"

namespace nix {

Expand Down
1 change: 1 addition & 0 deletions src/libstore/legacy-ssh-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "worker-protocol.hh"
#include "ssh.hh"
#include "derivations.hh"
#include "callback.hh"

namespace nix {

Expand Down
1 change: 1 addition & 0 deletions src/libstore/local-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "derivations.hh"
#include "nar-info.hh"
#include "references.hh"
#include "callback.hh"

#include <iostream>
#include <algorithm>
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "store-api.hh"
#include "thread-pool.hh"
#include "topo-sort.hh"

#include "callback.hh"

namespace nix {

Expand Down
1 change: 1 addition & 0 deletions src/libstore/remote-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "pool.hh"
#include "finally.hh"
#include "logging.hh"
#include "callback.hh"

#include <sys/types.h>
#include <sys/stat.h>
Expand Down
4 changes: 1 addition & 3 deletions src/libstore/store-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
#include "json.hh"
#include "url.hh"
#include "archive.hh"

#include <future>

#include "callback.hh"

namespace nix {

Expand Down
46 changes: 46 additions & 0 deletions src/libutil/callback.hh
Original file line number Diff line number Diff line change
@@ -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());
}
};

}
38 changes: 1 addition & 37 deletions src/libutil/util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <map>
#include <sstream>
#include <optional>
#include <future>
#include <iterator>

#ifndef HAVE_STRUCT_DIRENT_D_TYPE
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d51ba43

Please sign in to comment.