Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:13

0001 // Copyright (c) 2006, 2007 Julio M. Merino Vidal
0002 // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling
0003 // Copyright (c) 2009 Boris Schaeling
0004 // Copyright (c) 2010 Felipe Tanus, Boris Schaeling
0005 // Copyright (c) 2011, 2012 Jeff Flinn, Boris Schaeling
0006 // Copyright (c) 2016 Klemens D. Morgenstern
0007 //
0008 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 /**
0012  * \file boost/process/async_system.hpp
0013  *
0014  * Defines the asynchronous version of the system function.
0015  */
0016 
0017 #ifndef BOOST_PROCESS_ASYNC_SYSTEM_HPP
0018 #define BOOST_PROCESS_ASYNC_SYSTEM_HPP
0019 
0020 #include <boost/process/detail/config.hpp>
0021 #include <boost/process/async.hpp>
0022 #include <boost/process/child.hpp>
0023 #include <boost/process/detail/async_handler.hpp>
0024 #include <boost/process/detail/execute_impl.hpp>
0025 #include <type_traits>
0026 #include <memory>
0027 #include <boost/asio/async_result.hpp>
0028 #include <boost/asio/post.hpp>
0029 #include <boost/system/error_code.hpp>
0030 #include <tuple>
0031 
0032 #if defined(BOOST_POSIX_API)
0033 #include <boost/process/posix.hpp>
0034 #endif
0035 
0036 namespace boost {
0037 namespace process {
0038 namespace detail
0039 {
0040 
0041 template<typename Handler>
0042 struct async_system_handler : ::boost::process::detail::api::async_handler
0043 {
0044     boost::asio::io_context & ios;
0045     Handler handler;
0046 
0047 #if defined(BOOST_POSIX_API)
0048     bool errored = false;
0049 #endif
0050 
0051     template<typename ExitHandler_>
0052     async_system_handler(
0053             boost::asio::io_context & ios,
0054             ExitHandler_ && exit_handler) : ios(ios), handler(std::forward<ExitHandler_>(exit_handler))
0055     {
0056     }
0057 
0058 
0059     template<typename Exec>
0060     void on_error(Exec&, const std::error_code & ec)
0061     {
0062 #if defined(BOOST_POSIX_API)
0063         errored = true;
0064 #endif
0065         auto h = std::make_shared<Handler>(std::move(handler));
0066         boost::asio::post(
0067             ios.get_executor(),
0068             [h, ec]() mutable
0069             {
0070                 (*h)(boost::system::error_code(ec.value(), boost::system::system_category()), -1);
0071             });
0072     }
0073 
0074     template<typename Executor>
0075     std::function<void(int, const std::error_code&)> on_exit_handler(Executor&)
0076     {
0077 #if defined(BOOST_POSIX_API)
0078         if (errored)
0079             return [](int , const std::error_code &){};
0080 #endif
0081         auto h = std::make_shared<Handler>(std::move(handler));
0082         return [h](int exit_code, const std::error_code & ec) mutable
0083                {
0084                     (*h)(boost::system::error_code(ec.value(), boost::system::system_category()), exit_code);
0085                };
0086     }
0087 };
0088 
0089 
0090 template<typename ExitHandler>
0091 struct is_error_handler<async_system_handler<ExitHandler>>    : std::true_type {};
0092 
0093 }
0094 
0095 /** This function provides an asynchronous interface to process launching.
0096 
0097 It uses the same properties and parameters as the other launching function,
0098 but is similar to the asynchronous functions in [boost.asio](http://www.boost.org/doc/libs/release/doc/html/boost_asio.html)
0099 
0100 It uses [asio::async_result](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_result.html) to determine
0101 the return value (from the second parameter, `exit_handler`).
0102 
0103 \param ios A reference to an [io_context](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference.html)
0104 \param exit_handler The exit-handler for the signature `void(boost::system::error_code, int)`
0105 
0106 \note This function does not allow custom error handling, since those are done through the `exit_handler`.
0107 
0108 */
0109 #if defined(BOOST_PROCESS_DOXYGEN)
0110 template<typename ExitHandler, typename ...Args>
0111 inline boost::process::detail::dummy
0112     async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args);
0113 #endif
0114 
0115 namespace detail
0116 {
0117 struct async_system_init_op
0118 {
0119 
0120     template<typename Handler, typename ... Args>
0121     void operator()(Handler && handler, asio::io_context & ios, Args && ... args)
0122     {
0123         detail::async_system_handler<typename std::decay<Handler>::type> async_h{ios, std::forward<Handler>(handler)};
0124         child(ios, std::forward<Args>(args)..., async_h ).detach();
0125     }
0126 };
0127 
0128 
0129 }
0130 
0131 
0132 template<typename ExitHandler, typename ...Args>
0133 inline BOOST_ASIO_INITFN_RESULT_TYPE(ExitHandler, void (boost::system::error_code, int))
0134     async_system(boost::asio::io_context & ios, ExitHandler && exit_handler, Args && ...args)
0135 {
0136     
0137     typedef typename ::boost::process::detail::has_error_handler<boost::fusion::tuple<Args...>>::type
0138             has_err_handling;
0139 
0140     static_assert(!has_err_handling::value, "async_system cannot have custom error handling");
0141 
0142     return boost::asio::async_initiate<ExitHandler, void (boost::system::error_code, int)>(
0143         detail::async_system_init_op{}, exit_handler, ios, std::forward<Args>(args)...
0144     );
0145 }
0146 
0147 
0148 
0149 }}
0150 #endif
0151