aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/util.hh
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2018-03-27 22:16:01 +0200
committerEelco Dolstra <edolstra@gmail.com>2018-05-30 13:34:37 +0200
commit81ea8bd5ceb3dcae6af0b79c81a39ecbf2ba97a8 (patch)
tree2e96cec431e4ec67d8cfb50328a9da1b0c931145 /src/libutil/util.hh
parent1672bcd230447f1ce0c3291950bdd9a662cee974 (diff)
Simplify the callback mechanism
Diffstat (limited to 'src/libutil/util.hh')
-rw-r--r--src/libutil/util.hh53
1 files changed, 20 insertions, 33 deletions
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 743d23861..215c7ceca 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -15,6 +15,7 @@
#include <map>
#include <sstream>
#include <experimental/optional>
+#include <future>
#ifndef HAVE_STRUCT_DIRENT_D_TYPE
#define DT_UNKNOWN 0
@@ -424,44 +425,30 @@ string get(const T & map, const string & key, const string & def = "")
}
-/* Call ‘failure’ with the current exception as argument. If ‘failure’
- throws an exception, abort the program. */
-void callFailure(const std::function<void(std::exception_ptr exc)> & failure,
- std::exception_ptr exc = std::current_exception());
+/* 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>
+struct Callback
+{
+ std::function<void(std::future<T>)> fun;
+ Callback(std::function<void(std::future<T>)> fun) : fun(fun) { }
-/* Evaluate the function ‘f’. If it returns a value, call ‘success’
- with that value as its argument. If it or ‘success’ throws an
- exception, call ‘failure’. If ‘failure’ throws an exception, abort
- the program. */
-template<class T>
-void sync2async(
- const std::function<void(T)> & success,
- const std::function<void(std::exception_ptr exc)> & failure,
- const std::function<T()> & f)
-{
- try {
- success(f());
- } catch (...) {
- callFailure(failure);
+ void operator()(T && t) const
+ {
+ std::promise<T> promise;
+ promise.set_value(std::move(t));
+ fun(promise.get_future());
}
-}
-
-/* Call the function ‘success’. If it throws an exception, call
- ‘failure’. If that throws an exception, abort the program. */
-template<class T>
-void callSuccess(
- const std::function<void(T)> & success,
- const std::function<void(std::exception_ptr exc)> & failure,
- T && arg)
-{
- try {
- success(arg);
- } catch (...) {
- callFailure(failure);
+ void rethrow(const std::exception_ptr & exc = std::current_exception()) const
+ {
+ std::promise<T> promise;
+ promise.set_exception(exc);
+ fun(promise.get_future());
}
-}
+};
/* Start a thread that handles various signals. Also block those signals