]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // Copyright (c) 2016 Klemens D. Morgenstern |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | /** \file boost/process/async.hpp | |
7 | ||
8 | The header which provides the basic asynchrounous features. | |
9 | It provides the on_exit property, which allows callbacks when the process exits. | |
10 | It also implements the necessary traits for passing an boost::asio::io_context, | |
11 | which is needed for asynchronous communication. | |
12 | ||
13 | It also pulls the [boost::asio::buffer](http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html) | |
14 | into the boost::process namespace for convenience. | |
15 | ||
16 | \xmlonly | |
17 | <programlisting> | |
18 | namespace boost { | |
19 | namespace process { | |
20 | <emphasis>unspecified</emphasis> <ulink url="http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/buffer.html">buffer</ulink>; | |
21 | <emphasis>unspecified</emphasis> <globalname alt="boost::process::on_exit">on_exit</globalname>; | |
22 | } | |
23 | } | |
24 | </programlisting> | |
25 | ||
26 | \endxmlonly | |
27 | */ | |
28 | ||
29 | #ifndef BOOST_PROCESS_ASYNC_HPP_ | |
30 | #define BOOST_PROCESS_ASYNC_HPP_ | |
31 | ||
32 | #include <boost/process/detail/traits.hpp> | |
33 | #include <boost/process/detail/on_exit.hpp> | |
34 | ||
35 | #include <boost/asio/io_context.hpp> | |
36 | #include <boost/asio/streambuf.hpp> | |
37 | #include <boost/asio/buffer.hpp> | |
38 | #include <type_traits> | |
39 | #include <boost/fusion/iterator/deref.hpp> | |
40 | ||
41 | #if defined(BOOST_POSIX_API) | |
42 | #include <boost/process/detail/posix/io_context_ref.hpp> | |
43 | #include <boost/process/detail/posix/async_in.hpp> | |
44 | #include <boost/process/detail/posix/async_out.hpp> | |
45 | #include <boost/process/detail/posix/on_exit.hpp> | |
46 | ||
47 | #elif defined(BOOST_WINDOWS_API) | |
48 | #include <boost/process/detail/windows/io_context_ref.hpp> | |
49 | #include <boost/process/detail/windows/async_in.hpp> | |
50 | #include <boost/process/detail/windows/async_out.hpp> | |
51 | #include <boost/process/detail/windows/on_exit.hpp> | |
52 | #endif | |
53 | ||
54 | namespace boost { namespace process { namespace detail { | |
55 | ||
56 | struct async_tag; | |
57 | ||
58 | template<typename T> | |
59 | struct is_io_context : std::false_type {}; | |
60 | template<> | |
61 | struct is_io_context<api::io_context_ref> : std::true_type {}; | |
62 | ||
63 | template<typename Tuple> | |
64 | inline asio::io_context& get_io_context(const Tuple & tup) | |
65 | { | |
66 | auto& ref = *boost::fusion::find_if<is_io_context<boost::mpl::_>>(tup); | |
67 | return ref.get(); | |
68 | } | |
69 | ||
70 | struct async_builder | |
71 | { | |
72 | boost::asio::io_context * ios; | |
73 | ||
74 | void operator()(boost::asio::io_context & ios_) {this->ios = &ios_;}; | |
75 | ||
76 | typedef api::io_context_ref result_type; | |
77 | api::io_context_ref get_initializer() {return api::io_context_ref (*ios);}; | |
78 | }; | |
79 | ||
80 | ||
81 | template<> | |
82 | struct initializer_builder<async_tag> | |
83 | { | |
84 | typedef async_builder type; | |
85 | }; | |
86 | ||
87 | } | |
88 | ||
89 | using ::boost::asio::buffer; | |
90 | ||
91 | ||
92 | #if defined(BOOST_PROCESS_DOXYGEN) | |
93 | /** When an io_context is passed, the on_exit property can be used, to be notified | |
94 | when the child process exits. | |
95 | ||
96 | ||
97 | The following syntax is valid | |
98 | ||
99 | \code{.cpp} | |
100 | on_exit=function; | |
101 | on_exit(function); | |
102 | \endcode | |
103 | ||
104 | with `function` being a callable object with the signature `(int, const std::error_code&)` or an | |
105 | `std::future<int>`. | |
106 | ||
107 | \par Example | |
108 | ||
109 | \code{.cpp} | |
110 | io_context ios; | |
111 | ||
20effc67 | 112 | child c("ls", ios, on_exit=[](int exit, const std::error_code& ec_in){}); |
b32b8144 FG |
113 | |
114 | std::future<int> exit_code; | |
20effc67 | 115 | chlid c2("ls", ios, on_exit=exit_code); |
b32b8144 FG |
116 | |
117 | \endcode | |
118 | ||
119 | \note The handler is not invoked when the launch fails. | |
120 | \warning When used \ref ignore_error it might get invoked on error. | |
11fdf7f2 TL |
121 | \warning `on_exit` uses `boost::asio::signal_set` to listen for `SIGCHLD` on posix, and so has the |
122 | same restrictions as that class (do not register a handler for `SIGCHLD` except by using | |
123 | `boost::asio::signal_set`). | |
b32b8144 FG |
124 | */ |
125 | constexpr static ::boost::process::detail::on_exit_ on_exit{}; | |
126 | #endif | |
127 | ||
128 | }} | |
129 | ||
130 | ||
131 | ||
132 | #endif /* INCLUDE_BOOST_PROCESS_DETAIL_ASYNC_HPP_ */ |