summaryrefslogtreecommitdiff
path: root/boost/process/async_system.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/process/async_system.hpp')
-rw-r--r--boost/process/async_system.hpp142
1 files changed, 142 insertions, 0 deletions
diff --git a/boost/process/async_system.hpp b/boost/process/async_system.hpp
new file mode 100644
index 0000000000..f92b417d2e
--- /dev/null
+++ b/boost/process/async_system.hpp
@@ -0,0 +1,142 @@
+// Copyright (c) 2006, 2007 Julio M. Merino Vidal
+// Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
+// Copyright (c) 2009 Boris Schaeling
+// Copyright (c) 2010 Felipe Tanus, Boris Schaeling
+// Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
+// Copyright (c) 2016 Klemens D. Morgenstern
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/**
+ * \file boost/process/async_system.hpp
+ *
+ * Defines the asynchrounous version of the system function.
+ */
+
+#ifndef BOOST_PROCESS_ASYNC_SYSTEM_HPP
+#define BOOST_PROCESS_ASYNC_SYSTEM_HPP
+
+#include <boost/process/detail/config.hpp>
+#include <boost/process/async.hpp>
+#include <boost/process/child.hpp>
+#include <boost/process/detail/async_handler.hpp>
+#include <boost/process/detail/execute_impl.hpp>
+#include <type_traits>
+#include <memory>
+#include <boost/asio/async_result.hpp>
+#include <boost/system/error_code.hpp>
+#include <tuple>
+
+#if defined(BOOST_POSIX_API)
+#include <boost/process/posix.hpp>
+#endif
+
+namespace boost {
+namespace process {
+namespace detail
+{
+
+template<typename ExitHandler>
+struct async_system_handler : ::boost::process::detail::api::async_handler
+{
+ boost::asio::io_service & ios;
+ boost::asio::detail::async_result_init<
+ ExitHandler, void(boost::system::error_code, int)> init;
+
+#if defined(BOOST_POSIX_API)
+ bool errored = false;
+#endif
+
+ template<typename ExitHandler_>
+ async_system_handler(
+ boost::asio::io_service & ios,
+ ExitHandler_ && exit_handler) : ios(ios), init(std::forward<ExitHandler_>(exit_handler))
+ {
+
+ }
+
+
+ template<typename Exec>
+ void on_error(Exec&, const std::error_code & ec)
+ {
+#if defined(BOOST_POSIX_API)
+ errored = true;
+#endif
+ auto & h = init.handler;
+ ios.post(
+ [h, ec]() mutable
+ {
+ h(boost::system::error_code(ec.value(), boost::system::system_category()), -1);
+ });
+ }
+
+ BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int))
+ get_result()
+ {
+ return init.result.get();
+ }
+
+ template<typename Executor>
+ std::function<void(int, const std::error_code&)> on_exit_handler(Executor&)
+ {
+#if defined(BOOST_POSIX_API)
+ if (errored)
+ return [](int exit_code, const std::error_code & ec){};
+#endif
+ auto & h = init.handler;
+ return [h](int exit_code, const std::error_code & ec) mutable
+ {
+ h(boost::system::error_code(ec.value(), boost::system::system_category()), exit_code);
+ };
+ }
+};
+
+
+template<typename ExitHandler>
+struct is_error_handler<async_system_handler<ExitHandler>> : std::true_type {};
+
+}
+
+/** This function provides an asynchronous interface to process launching.
+
+It uses the same properties and parameters as the other launching function,
+but is similar to the asynchronous functions in [boost.asio](http://www.boost.org/doc/libs/release/doc/html/boost_asio.html)
+
+It uses [asio::async_result](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_result.html) to determine
+the return value (from the second parameter, `exit_handler`).
+
+\param ios A reference to an [io_service](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference.html)
+\param exit_handler The exit-handler for the signature `void(boost::system::error_code, int)`
+
+\note This function does not allow custom error handling, since those are done through the `exit_handler`.
+
+*/
+#if defined(BOOST_PROCESS_DOXYGEN)
+template<typename ExitHandler, typename ...Args>
+inline boost::process::detail::dummy
+ async_system(boost::asio::io_service & ios, ExitHandler && exit_handler, Args && ...args);
+#endif
+
+template<typename ExitHandler, typename ...Args>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int))
+ async_system(boost::asio::io_service & ios, ExitHandler && exit_handler, Args && ...args)
+{
+ detail::async_system_handler<ExitHandler> async_h{ios, std::forward<ExitHandler>(exit_handler)};
+
+ typedef typename ::boost::process::detail::has_error_handler<boost::fusion::tuple<Args...>>::type
+ has_err_handling;
+
+ static_assert(!has_err_handling::value, "async_system cannot have custom error handling");
+
+
+ child(ios, std::forward<Args>(args)..., async_h ).detach();
+
+ return async_h.get_result();
+}
+
+
+
+}}
+#endif
+