2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "anbox/logger.h"
21 #include "anbox/runtime.h"
24 // exception_safe_run runs service, catching all exceptions and
25 // restarting operation until an explicit shutdown has been requested.
27 // TODO(tvoss): Catching all exceptions is risky as they might signal
29 // errors. We should enable calling code to decide whether an exception should
32 void exception_safe_run(boost::asio::io_service& service) {
36 // a clean return from run only happens in case of
37 // stop() being called (we are keeping the service alive with
38 // a service::work instance).
40 } catch (const std::exception& e) {
41 ERROR("%s", e.what());
43 ERROR("Unknown exception caught while executing boost::asio::io_service");
50 std::shared_ptr<Runtime> Runtime::create(std::uint32_t pool_size) {
51 return std::shared_ptr<Runtime>(new Runtime(pool_size));
54 Runtime::Runtime(std::uint32_t pool_size)
55 : pool_size_{pool_size},
57 #if BOOST_VERSION >= 106600
58 service_{static_cast<int>(pool_size_)},
64 keep_alive_{service_} {}
66 Runtime::~Runtime() noexcept(true) {
70 // Dropping all exceptions to satisfy the nothrow guarantee.
74 void Runtime::start() {
75 for (unsigned int i = 0; i < pool_size_; i++)
76 workers_.push_back(std::thread{exception_safe_run, std::ref(service_)});
79 void Runtime::stop() {
82 for (auto& worker : workers_)
83 if (worker.joinable())
87 std::function<void(std::function<void()>)> Runtime::to_dispatcher_functional() {
88 // We have to make sure that we stay alive for as long as
89 // calling code requires the dispatcher to work.
90 auto sp = shared_from_this();
91 return [sp](std::function<void()> task) { sp->strand_.post(task); };
94 boost::asio::io_service& Runtime::service() { return service_; }