diff options
Diffstat (limited to 'libtransport/includes/hicn/transport/utils/event_thread.h')
-rw-r--r-- | libtransport/includes/hicn/transport/utils/event_thread.h | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/libtransport/includes/hicn/transport/utils/event_thread.h b/libtransport/includes/hicn/transport/utils/event_thread.h index 702c98f8d..164c853a5 100644 --- a/libtransport/includes/hicn/transport/utils/event_thread.h +++ b/libtransport/includes/hicn/transport/utils/event_thread.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -16,45 +16,57 @@ #pragma once #include <hicn/transport/config.h> +#include <hicn/transport/core/asio_wrapper.h> #include <hicn/transport/errors/runtime_exception.h> -#include <asio.hpp> #include <memory> #include <thread> namespace utils { class EventThread { - private: - // No copies - EventThread(const EventThread&) = delete; // non construction-copyable - EventThread& operator=(const EventThread&) = delete; // non copyable - public: - explicit EventThread(asio::io_service& io_service) + EventThread(asio::io_service& io_service, bool detached = false) : internal_io_service_(nullptr), - io_service_(io_service), - work_(std::make_unique<asio::io_service::work>(io_service_)), - thread_(nullptr) { + io_service_(std::ref(io_service)), + work_guard_(asio::make_work_guard(io_service_.get())), + thread_(nullptr), + detached_(detached) { run(); } - explicit EventThread() + explicit EventThread(bool detached = false) : internal_io_service_(std::make_unique<asio::io_service>()), - io_service_(*internal_io_service_), - work_(std::make_unique<asio::io_service::work>(io_service_)), - thread_(nullptr) { + io_service_(std::ref(*internal_io_service_)), + work_guard_(asio::make_work_guard(io_service_.get())), + thread_(nullptr), + detached_(detached) { run(); } + EventThread(const EventThread&) = delete; + EventThread& operator=(const EventThread&) = delete; + + EventThread(EventThread&& other) noexcept + : internal_io_service_(std::move(other.internal_io_service_)), + io_service_(std::move(other.io_service_)), + work_guard_(std::move(other.work_guard_)), + thread_(std::move(other.thread_)), + detached_(other.detached_) {} + ~EventThread() { stop(); } void run() { if (stopped()) { - io_service_.reset(); + io_service_.get().stopped(); } - thread_ = std::make_unique<std::thread>([this]() { io_service_.run(); }); + thread_ = + std::make_unique<std::thread>([this]() { io_service_.get().run(); }); + + if (detached_) { + thread_->detach(); + } } std::thread::id getThreadId() const { @@ -67,18 +79,29 @@ class EventThread { template <typename Func> void add(Func&& f) { - // If the function f - // TODO USe post in mac os, asio->post in xenial - io_service_.post(std::forward<Func&&>(f)); + io_service_.get().post(std::forward<Func>(f)); } template <typename Func> void tryRunHandlerNow(Func&& f) { - io_service_.dispatch(std::forward<Func&&>(f)); + io_service_.get().dispatch(std::forward<Func>(f)); + } + + template <typename Func> + void addAndWaitForExecution(Func&& f) const { + auto promise = std::promise<void>(); + auto future = promise.get_future(); + + asio::dispatch(io_service_.get(), [&promise, f = std::forward<Func>(f)]() { + f(); + promise.set_value(); + }); + + future.wait(); } void stop() { - work_.reset(); + add([this]() { work_guard_.reset(); }); if (thread_ && thread_->joinable()) { thread_->join(); @@ -87,15 +110,16 @@ class EventThread { thread_.reset(); } - bool stopped() { return io_service_.stopped(); } + bool stopped() const { return io_service_.get().stopped(); } asio::io_service& getIoService() { return io_service_; } private: std::unique_ptr<asio::io_service> internal_io_service_; - asio::io_service& io_service_; - std::unique_ptr<asio::io_service::work> work_; + std::reference_wrapper<asio::io_service> io_service_; + asio::executor_work_guard<asio::io_context::executor_type> work_guard_; std::unique_ptr<std::thread> thread_; + bool detached_; }; } // namespace utils
\ No newline at end of file |