TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / runtime.cpp
diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/runtime.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/runtime.cpp
new file mode 100644 (file)
index 0000000..90c6768
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <iostream>
+
+#include "anbox/logger.h"
+#include "anbox/runtime.h"
+
+namespace {
+// exception_safe_run runs service, catching all exceptions and
+// restarting operation until an explicit shutdown has been requested.
+//
+// TODO(tvoss): Catching all exceptions is risky as they might signal
+// unrecoverable
+// errors. We should enable calling code to decide whether an exception should
+// be considered
+// fatal or not.
+void exception_safe_run(boost::asio::io_service& service) {
+  while (true) {
+    try {
+      service.run();
+      // a clean return from run only happens in case of
+      // stop() being called (we are keeping the service alive with
+      // a service::work instance).
+      break;
+    } catch (const std::exception& e) {
+      ERROR("%s", e.what());
+    } catch (...) {
+      ERROR("Unknown exception caught while executing boost::asio::io_service");
+    }
+  }
+}
+}
+namespace anbox {
+
+std::shared_ptr<Runtime> Runtime::create(std::uint32_t pool_size) {
+  return std::shared_ptr<Runtime>(new Runtime(pool_size));
+}
+
+Runtime::Runtime(std::uint32_t pool_size)
+    : pool_size_{pool_size},
+      
+      #if BOOST_VERSION >= 106600
+      service_{static_cast<int>(pool_size_)},
+      #else
+      service_{pool_size_},
+      #endif
+      
+      strand_{service_},
+      keep_alive_{service_} {}
+
+Runtime::~Runtime() noexcept(true) {
+  try {
+    stop();
+  } catch (...) {
+    // Dropping all exceptions to satisfy the nothrow guarantee.
+  }
+}
+
+void Runtime::start() {
+  for (unsigned int i = 0; i < pool_size_; i++)
+    workers_.push_back(std::thread{exception_safe_run, std::ref(service_)});
+}
+
+void Runtime::stop() {
+  service_.stop();
+
+  for (auto& worker : workers_)
+    if (worker.joinable())
+      worker.join();
+}
+
+std::function<void(std::function<void()>)> Runtime::to_dispatcher_functional() {
+  // We have to make sure that we stay alive for as long as
+  // calling code requires the dispatcher to work.
+  auto sp = shared_from_this();
+  return [sp](std::function<void()> task) { sp->strand_.post(task); };
+}
+
+boost::asio::io_service& Runtime::service() { return service_; }
+
+}  // namespace anbox