From b27216a50bd6566b6fd9203d3acf191005ae5763 Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 16 Nov 2018 17:05:28 -0500 Subject: clean up code --- include/salticidae/event.h | 89 +++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 32 deletions(-) (limited to 'include/salticidae/event.h') diff --git a/include/salticidae/event.h b/include/salticidae/event.h index 2cda44f..0498fa5 100644 --- a/include/salticidae/event.h +++ b/include/salticidae/event.h @@ -192,22 +192,23 @@ class Event { operator bool() const { return ev_fd != nullptr || ev_timer != nullptr; } }; +template class ThreadNotifier { std::condition_variable cv; std::mutex mlock; mutex_ul_t ul; bool ready; - void *data; + T data; public: ThreadNotifier(): ul(mlock), ready(false) {} - void *wait() { + T wait() { cv.wait(ul, [this]{ return ready; }); - return data; + return std::move(data); } - void notify(void *_data) { + void notify(T &&_data) { mutex_lg_t _(mlock); ready = true; - data = _data; + data = std::move(_data); cv.notify_all(); } }; @@ -218,21 +219,50 @@ class ThreadCall { Event ev_listen; public: + struct Result { + void *data; + std::function deleter; + Result(): data(nullptr) {} + Result(void *data, std::function &&deleter): + data(data), deleter(std::move(deleter)) {} + ~Result() { if (data != nullptr) deleter(data); } + Result(const Result &) = delete; + Result(Result &&other): + data(other.data), deleter(std::move(other.deleter)) { + other.data = nullptr; + } + void swap(Result &other) { + std::swap(data, other.data); + std::swap(deleter, other.deleter); + } + Result &operator=(const Result &other) = delete; + Result &operator=(Result &&other) { + if (this != &other) + { + Result tmp(std::move(other)); + tmp.swap(*this); + } + return *this; + } + void *get() { return data; } + }; class Handle { std::function callback; - std::function deleter; - ThreadNotifier* notifier; - void *result; + ThreadNotifier * notifier; + Result result; friend ThreadCall; public: - Handle(): notifier(nullptr), result(nullptr) {} + Handle(): notifier(nullptr) {} void exec() { callback(*this); - if (notifier) notifier->notify(result); + if (notifier) + notifier->notify(std::move(result)); + } + template + void set_result(T data) { + result = Result(new T(std::forward(data)), + [](void *ptr) {delete static_cast(ptr);}); } - void set_result(void *data) { result = data; } - template - void set_deleter(Func _deleter) { deleter = _deleter; } }; ThreadCall() = default; @@ -254,33 +284,28 @@ class ThreadCall { ev_listen.clear(); Handle *h; while (read(ctl_fd[0], &h, sizeof(h)) == sizeof(h)) - { - if (h->result && h->deleter) - h->deleter(h->result); delete h; - } close(ctl_fd[0]); close(ctl_fd[1]); } template - void *call(Func callback, bool blocking = false) { + void async_call(Func callback) { auto h = new Handle(); h->callback = callback; - if (blocking) - { - ThreadNotifier notifier; - h->notifier = ¬ifier; - std::atomic_thread_fence(std::memory_order_release); - write(ctl_fd[1], &h, sizeof(h)); - return notifier.wait(); - } - else - { - std::atomic_thread_fence(std::memory_order_release); - write(ctl_fd[1], &h, sizeof(h)); - return nullptr; - } + std::atomic_thread_fence(std::memory_order_release); + write(ctl_fd[1], &h, sizeof(h)); + } + + template + Result call(Func callback) { + auto h = new Handle(); + h->callback = callback; + ThreadNotifier notifier; + h->notifier = ¬ifier; + std::atomic_thread_fence(std::memory_order_release); + write(ctl_fd[1], &h, sizeof(h)); + return notifier.wait(); } }; -- cgit v1.2.3