]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // detail/impl/reactive_descriptor_service.ipp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP | |
12 | #define BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP | |
13 | ||
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) | |
15 | # pragma once | |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) | |
17 | ||
18 | #include <boost/asio/detail/config.hpp> | |
19 | ||
20 | #if !defined(BOOST_ASIO_WINDOWS) \ | |
21 | && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \ | |
22 | && !defined(__CYGWIN__) | |
23 | ||
24 | #include <boost/asio/error.hpp> | |
25 | #include <boost/asio/detail/reactive_descriptor_service.hpp> | |
26 | ||
27 | #include <boost/asio/detail/push_options.hpp> | |
28 | ||
29 | namespace boost { | |
30 | namespace asio { | |
31 | namespace detail { | |
32 | ||
33 | reactive_descriptor_service::reactive_descriptor_service( | |
92f5a8d4 TL |
34 | execution_context& context) |
35 | : execution_context_service_base<reactive_descriptor_service>(context), | |
36 | reactor_(boost::asio::use_service<reactor>(context)) | |
7c673cae FG |
37 | { |
38 | reactor_.init_task(); | |
39 | } | |
40 | ||
b32b8144 | 41 | void reactive_descriptor_service::shutdown() |
7c673cae FG |
42 | { |
43 | } | |
44 | ||
45 | void reactive_descriptor_service::construct( | |
46 | reactive_descriptor_service::implementation_type& impl) | |
47 | { | |
48 | impl.descriptor_ = -1; | |
49 | impl.state_ = 0; | |
50 | } | |
51 | ||
52 | void reactive_descriptor_service::move_construct( | |
53 | reactive_descriptor_service::implementation_type& impl, | |
54 | reactive_descriptor_service::implementation_type& other_impl) | |
f67539c2 | 55 | BOOST_ASIO_NOEXCEPT |
7c673cae FG |
56 | { |
57 | impl.descriptor_ = other_impl.descriptor_; | |
58 | other_impl.descriptor_ = -1; | |
59 | ||
60 | impl.state_ = other_impl.state_; | |
61 | other_impl.state_ = 0; | |
62 | ||
63 | reactor_.move_descriptor(impl.descriptor_, | |
64 | impl.reactor_data_, other_impl.reactor_data_); | |
65 | } | |
66 | ||
67 | void reactive_descriptor_service::move_assign( | |
68 | reactive_descriptor_service::implementation_type& impl, | |
69 | reactive_descriptor_service& other_service, | |
70 | reactive_descriptor_service::implementation_type& other_impl) | |
71 | { | |
72 | destroy(impl); | |
73 | ||
74 | impl.descriptor_ = other_impl.descriptor_; | |
75 | other_impl.descriptor_ = -1; | |
76 | ||
77 | impl.state_ = other_impl.state_; | |
78 | other_impl.state_ = 0; | |
79 | ||
80 | other_service.reactor_.move_descriptor(impl.descriptor_, | |
81 | impl.reactor_data_, other_impl.reactor_data_); | |
82 | } | |
83 | ||
84 | void reactive_descriptor_service::destroy( | |
85 | reactive_descriptor_service::implementation_type& impl) | |
86 | { | |
87 | if (is_open(impl)) | |
88 | { | |
b32b8144 FG |
89 | BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), |
90 | "descriptor", &impl, impl.descriptor_, "close")); | |
7c673cae FG |
91 | |
92 | reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, | |
93 | (impl.state_ & descriptor_ops::possible_dup) == 0); | |
7c673cae | 94 | |
b32b8144 FG |
95 | boost::system::error_code ignored_ec; |
96 | descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec); | |
97 | ||
98 | reactor_.cleanup_descriptor_data(impl.reactor_data_); | |
99 | } | |
7c673cae FG |
100 | } |
101 | ||
102 | boost::system::error_code reactive_descriptor_service::assign( | |
103 | reactive_descriptor_service::implementation_type& impl, | |
104 | const native_handle_type& native_descriptor, boost::system::error_code& ec) | |
105 | { | |
106 | if (is_open(impl)) | |
107 | { | |
108 | ec = boost::asio::error::already_open; | |
109 | return ec; | |
110 | } | |
111 | ||
112 | if (int err = reactor_.register_descriptor( | |
113 | native_descriptor, impl.reactor_data_)) | |
114 | { | |
115 | ec = boost::system::error_code(err, | |
116 | boost::asio::error::get_system_category()); | |
117 | return ec; | |
118 | } | |
119 | ||
120 | impl.descriptor_ = native_descriptor; | |
121 | impl.state_ = descriptor_ops::possible_dup; | |
122 | ec = boost::system::error_code(); | |
123 | return ec; | |
124 | } | |
125 | ||
126 | boost::system::error_code reactive_descriptor_service::close( | |
127 | reactive_descriptor_service::implementation_type& impl, | |
128 | boost::system::error_code& ec) | |
129 | { | |
130 | if (is_open(impl)) | |
131 | { | |
b32b8144 FG |
132 | BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), |
133 | "descriptor", &impl, impl.descriptor_, "close")); | |
7c673cae FG |
134 | |
135 | reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, | |
136 | (impl.state_ & descriptor_ops::possible_dup) == 0); | |
7c673cae | 137 | |
b32b8144 FG |
138 | descriptor_ops::close(impl.descriptor_, impl.state_, ec); |
139 | ||
140 | reactor_.cleanup_descriptor_data(impl.reactor_data_); | |
141 | } | |
142 | else | |
143 | { | |
144 | ec = boost::system::error_code(); | |
145 | } | |
7c673cae FG |
146 | |
147 | // The descriptor is closed by the OS even if close() returns an error. | |
148 | // | |
149 | // (Actually, POSIX says the state of the descriptor is unspecified. On | |
150 | // Linux the descriptor is apparently closed anyway; e.g. see | |
151 | // http://lkml.org/lkml/2005/9/10/129 | |
152 | // We'll just have to assume that other OSes follow the same behaviour.) | |
153 | construct(impl); | |
154 | ||
155 | return ec; | |
156 | } | |
157 | ||
158 | reactive_descriptor_service::native_handle_type | |
159 | reactive_descriptor_service::release( | |
160 | reactive_descriptor_service::implementation_type& impl) | |
161 | { | |
162 | native_handle_type descriptor = impl.descriptor_; | |
163 | ||
164 | if (is_open(impl)) | |
165 | { | |
b32b8144 FG |
166 | BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), |
167 | "descriptor", &impl, impl.descriptor_, "release")); | |
7c673cae FG |
168 | |
169 | reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false); | |
b32b8144 | 170 | reactor_.cleanup_descriptor_data(impl.reactor_data_); |
7c673cae FG |
171 | construct(impl); |
172 | } | |
173 | ||
174 | return descriptor; | |
175 | } | |
176 | ||
177 | boost::system::error_code reactive_descriptor_service::cancel( | |
178 | reactive_descriptor_service::implementation_type& impl, | |
179 | boost::system::error_code& ec) | |
180 | { | |
181 | if (!is_open(impl)) | |
182 | { | |
183 | ec = boost::asio::error::bad_descriptor; | |
184 | return ec; | |
185 | } | |
186 | ||
b32b8144 FG |
187 | BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), |
188 | "descriptor", &impl, impl.descriptor_, "cancel")); | |
7c673cae FG |
189 | |
190 | reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_); | |
191 | ec = boost::system::error_code(); | |
192 | return ec; | |
193 | } | |
194 | ||
195 | void reactive_descriptor_service::start_op( | |
196 | reactive_descriptor_service::implementation_type& impl, | |
197 | int op_type, reactor_op* op, bool is_continuation, | |
198 | bool is_non_blocking, bool noop) | |
199 | { | |
200 | if (!noop) | |
201 | { | |
202 | if ((impl.state_ & descriptor_ops::non_blocking) || | |
203 | descriptor_ops::set_internal_non_blocking( | |
204 | impl.descriptor_, impl.state_, true, op->ec_)) | |
205 | { | |
206 | reactor_.start_op(op_type, impl.descriptor_, | |
207 | impl.reactor_data_, op, is_continuation, is_non_blocking); | |
208 | return; | |
209 | } | |
210 | } | |
211 | ||
212 | reactor_.post_immediate_completion(op, is_continuation); | |
213 | } | |
214 | ||
215 | } // namespace detail | |
216 | } // namespace asio | |
217 | } // namespace boost | |
218 | ||
219 | #include <boost/asio/detail/pop_options.hpp> | |
220 | ||
221 | #endif // !defined(BOOST_ASIO_WINDOWS) | |
222 | // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) | |
223 | // && !defined(__CYGWIN__) | |
224 | ||
225 | #endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP |