@@ -145,6 +145,79 @@ asio::socket& socket::get_transport() NOEXCEPT
145145 return websocket () ? beast::get_lowest_layer (*websocket_) : socket_;
146146}
147147
148+ // Wait.
149+ // ----------------------------------------------------------------------------
150+
151+ void socket::wait (result_handler&& handler) NOEXCEPT
152+ {
153+ boost::asio::dispatch (strand_,
154+ std::bind (&socket::do_wait,
155+ shared_from_this (), std::move (handler)));
156+ }
157+
158+ // private
159+ void socket::do_wait (const result_handler& handler) NOEXCEPT
160+ {
161+ BC_ASSERT (stranded ());
162+
163+ get_transport ().async_wait (asio::socket::wait_read,
164+ std::bind (&socket::handle_wait,
165+ shared_from_this (), _1, handler));
166+ }
167+
168+ // private
169+ void socket::handle_wait (const boost_code& ec,
170+ const result_handler& handler) NOEXCEPT
171+ {
172+ BC_ASSERT (stranded ());
173+
174+ // Only wait cancel results in caller not calling stop.
175+ if (error::asio_is_canceled (ec))
176+ {
177+ handler (error::success);
178+ return ;
179+ }
180+
181+ if (ec)
182+ {
183+ handler (error::asio_to_error_code (ec));
184+ return ;
185+ }
186+
187+ handler (error::operation_canceled);
188+ }
189+
190+ void socket::cancel (result_handler&& handler) NOEXCEPT
191+ {
192+ boost::asio::dispatch (strand_,
193+ std::bind (&socket::do_cancel,
194+ shared_from_this (), std::move (handler)));
195+ }
196+
197+ // private
198+ void socket::do_cancel (const result_handler& handler) NOEXCEPT
199+ {
200+ BC_ASSERT (stranded ());
201+
202+ if (stopped ())
203+ {
204+ handler (error::success);
205+ return ;
206+ }
207+
208+ try
209+ {
210+ // Causes connect, send, and receive calls to quit with
211+ // asio::error::operation_aborted passed to handlers.
212+ socket_.cancel ();
213+ }
214+ catch (const std::exception& LOG_ONLY (e))
215+ {
216+ LOGF (" Exception @ do_cancel: " << e.what ());
217+ handler (error::service_stopped);
218+ }
219+ }
220+
148221// Connection.
149222// ----------------------------------------------------------------------------
150223// Boost async functions are NOT THREAD SAFE for the same socket object.
@@ -168,7 +241,7 @@ void socket::accept(asio::acceptor& acceptor,
168241 // Dispatches on the acceptor's strand (which should be network).
169242 acceptor.async_accept (socket_,
170243 std::bind (&socket::handle_accept,
171- shared_from_this (), _1, handler));
244+ shared_from_this (), _1, std::move ( handler) ));
172245 }
173246 catch (const std::exception& LOG_ONLY (e))
174247 {
0 commit comments