From d51ba430473368b29abfd1a8c4655da74b3a780c Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Mon, 21 Sep 2020 18:40:11 +0200
Subject: [PATCH] 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.
---
 src/libstore/binary-cache-store.cc      |  1 +
 src/libstore/build.cc                   |  1 +
 src/libstore/dummy-store.cc             |  1 +
 src/libstore/filetransfer.cc            |  1 +
 src/libstore/http-binary-cache-store.cc |  1 +
 src/libstore/legacy-ssh-store.cc        |  1 +
 src/libstore/local-store.cc             |  1 +
 src/libstore/misc.cc                    |  2 +-
 src/libstore/remote-store.cc            |  1 +
 src/libstore/store-api.cc               |  4 +--
 src/libutil/callback.hh                 | 46 +++++++++++++++++++++++++
 src/libutil/util.hh                     | 38 +-------------------
 12 files changed, 57 insertions(+), 41 deletions(-)
 create mode 100644 src/libutil/callback.hh

diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 34f844a18..ebc0bd6a4 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 6e55f83d5..0b51d90ea 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 128832e60..49641c2ac 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 4149f8155..6241b5e00 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 f4ab15a10..86be7c006 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 e9478c1d5..5af75669a 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 c618203f0..94ff34cb8 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 da3981696..ad4dccef9 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 e92b94975..27535f1d0 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 2d5077ed0..1bbc74db8 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 000000000..ef31794be
--- /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 082e26375..91e0a1543 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
-- 
GitLab