TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / runtime.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
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.
7  *
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.
12  *
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/>.
15  *
16  */
17
18 #include <iostream>
19
20 #include "anbox/logger.h"
21 #include "anbox/runtime.h"
22
23 namespace {
24 // exception_safe_run runs service, catching all exceptions and
25 // restarting operation until an explicit shutdown has been requested.
26 //
27 // TODO(tvoss): Catching all exceptions is risky as they might signal
28 // unrecoverable
29 // errors. We should enable calling code to decide whether an exception should
30 // be considered
31 // fatal or not.
32 void exception_safe_run(boost::asio::io_service& service) {
33   while (true) {
34     try {
35       service.run();
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).
39       break;
40     } catch (const std::exception& e) {
41       ERROR("%s", e.what());
42     } catch (...) {
43       ERROR("Unknown exception caught while executing boost::asio::io_service");
44     }
45   }
46 }
47 }
48 namespace anbox {
49
50 std::shared_ptr<Runtime> Runtime::create(std::uint32_t pool_size) {
51   return std::shared_ptr<Runtime>(new Runtime(pool_size));
52 }
53
54 Runtime::Runtime(std::uint32_t pool_size)
55     : pool_size_{pool_size},
56       
57       #if BOOST_VERSION >= 106600
58       service_{static_cast<int>(pool_size_)},
59       #else
60       service_{pool_size_},
61       #endif
62       
63       strand_{service_},
64       keep_alive_{service_} {}
65
66 Runtime::~Runtime() noexcept(true) {
67   try {
68     stop();
69   } catch (...) {
70     // Dropping all exceptions to satisfy the nothrow guarantee.
71   }
72 }
73
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_)});
77 }
78
79 void Runtime::stop() {
80   service_.stop();
81
82   for (auto& worker : workers_)
83     if (worker.joinable())
84       worker.join();
85 }
86
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); };
92 }
93
94 boost::asio::io_service& Runtime::service() { return service_; }
95
96 }  // namespace anbox