11 #ifndef ASIO_IMPL_IO_CONTEXT_HPP 12 #define ASIO_IMPL_IO_CONTEXT_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 #include "asio/detail/completion_handler.hpp" 19 #include "asio/detail/executor_op.hpp" 20 #include "asio/detail/fenced_block.hpp" 21 #include "asio/detail/handler_type_requirements.hpp" 22 #include "asio/detail/non_const_lvalue.hpp" 23 #include "asio/detail/recycling_allocator.hpp" 24 #include "asio/detail/service_registry.hpp" 25 #include "asio/detail/throw_error.hpp" 26 #include "asio/detail/type_traits.hpp" 28 #include "asio/detail/push_options.hpp" 32 #if !defined(GENERATING_DOCUMENTATION) 34 template <
typename Service>
38 (void)static_cast<execution_context::service*>(static_cast<Service*>(0));
39 (void)static_cast<const execution_context::id*>(&Service::id);
41 return ioc.service_registry_->template use_service<Service>(ioc);
51 #endif // !defined(GENERATING_DOCUMENTATION) 59 #if defined(ASIO_HAS_CHRONO) 61 template <
typename Rep,
typename Period>
62 std::size_t io_context::run_for(
63 const chrono::duration<Rep, Period>& rel_time)
65 return this->run_until(chrono::steady_clock::now() + rel_time);
68 template <
typename Clock,
typename Duration>
69 std::size_t io_context::run_until(
70 const chrono::time_point<Clock, Duration>& abs_time)
73 while (this->run_one_until(abs_time))
74 if (n != (std::numeric_limits<std::size_t>::max)())
79 template <
typename Rep,
typename Period>
80 std::size_t io_context::run_one_for(
81 const chrono::duration<Rep, Period>& rel_time)
83 return this->run_one_until(chrono::steady_clock::now() + rel_time);
86 template <
typename Clock,
typename Duration>
87 std::size_t io_context::run_one_until(
88 const chrono::time_point<Clock, Duration>& abs_time)
90 typename Clock::time_point now = Clock::now();
91 while (now < abs_time)
93 typename Clock::duration rel_time = abs_time - now;
94 if (rel_time > chrono::seconds(1))
95 rel_time = chrono::seconds(1);
98 std::size_t
s = impl_.wait_one(
99 static_cast<long>(chrono::duration_cast<
100 chrono::microseconds>(rel_time).count()), ec);
101 asio::detail::throw_error(ec);
103 if (s || impl_.stopped())
112 #endif // defined(ASIO_HAS_CHRONO) 114 #if !defined(ASIO_NO_DEPRECATED) 123 template <
typename LegacyCompletionHandler>
124 void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
129 ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
130 LegacyCompletionHandler, handler) type_check;
133 if (self->impl_.can_dispatch())
136 asio_handler_invoke_helpers::invoke(
137 handler2.value, handler2.value);
143 typename decay<LegacyCompletionHandler>::type,
executor_type> op;
144 typename op::ptr p = { detail::addressof(handler2.value),
145 op::ptr::allocate(handler2.value), 0 };
146 p.p =
new (p.v) op(handler2.value, self->get_executor());
148 ASIO_HANDLER_CREATION((*
self, *p.p,
149 "io_context",
self, 0,
"dispatch"));
151 self->impl_.do_dispatch(p.p);
157 template <
typename LegacyCompletionHandler>
161 return async_initiate<LegacyCompletionHandler, void ()>(
167 template <
typename LegacyCompletionHandler>
168 void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
173 ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
174 LegacyCompletionHandler, handler) type_check;
178 bool is_continuation =
179 asio_handler_cont_helpers::is_continuation(handler2.value);
183 typename decay<LegacyCompletionHandler>::type,
executor_type> op;
184 typename op::ptr p = { detail::addressof(handler2.value),
185 op::ptr::allocate(handler2.value), 0 };
186 p.p =
new (p.v) op(handler2.value, self->get_executor());
188 ASIO_HANDLER_CREATION((*
self, *p.p,
189 "io_context",
self, 0,
"post"));
191 self->impl_.post_immediate_completion(p.p, is_continuation);
196 template <
typename LegacyCompletionHandler>
200 return async_initiate<LegacyCompletionHandler, void ()>(
204 template <
typename Handler>
205 #if defined(GENERATING_DOCUMENTATION) 215 #endif // !defined(ASIO_NO_DEPRECATED) 217 template <
typename Allocator,
unsigned int Bits>
225 io_context_ = other.io_context_;
226 allocator_ = other.allocator_;
228 if (Bits & outstanding_work_tracked)
231 io_context_->impl_.work_started();
233 old_io_context->impl_.work_finished();
239 #if defined(ASIO_HAS_MOVE) 240 template <
typename Allocator,
unsigned int Bits>
247 io_context_ = other.io_context_;
248 allocator_ = std::move(other.allocator_);
250 if (Bits & outstanding_work_tracked)
251 other.io_context_ = 0;
255 #endif // defined(ASIO_HAS_MOVE) 257 template <
typename Allocator,
unsigned int Bits>
259 Bits>::running_in_this_thread() const ASIO_NOEXCEPT
261 return io_context_->impl_.can_dispatch();
264 template <
typename Allocator,
unsigned int Bits>
265 template <
typename Function>
267 ASIO_MOVE_ARG(Function) f)
const 269 typedef typename decay<Function>::type function_type;
273 if ((bits_ & blocking_never) == 0 && io_context_->impl_.can_dispatch())
276 function_type tmp(ASIO_MOVE_CAST(Function)(f));
278 #if defined(ASIO_HAS_STD_EXCEPTION_PTR) \ 279 && !defined(ASIO_NO_EXCEPTIONS) 282 #endif // defined(ASIO_HAS_STD_EXCEPTION_PTR) 285 asio_handler_invoke_helpers::invoke(tmp, tmp);
287 #if defined(ASIO_HAS_STD_EXCEPTION_PTR) \ 288 && !defined(ASIO_NO_EXCEPTIONS) 292 io_context_->impl_.capture_current_exception();
295 #endif // defined(ASIO_HAS_STD_EXCEPTION_PTR) 301 typename op::ptr p = { detail::addressof(allocator_),
302 op::ptr::allocate(allocator_), 0 };
303 p.p =
new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_);
305 ASIO_HANDLER_CREATION((*io_context_, *p.p,
306 "io_context", io_context_, 0,
"execute"));
308 io_context_->impl_.post_immediate_completion(p.p,
309 (bits_ & relationship_continuation) != 0);
313 #if !defined(ASIO_NO_TS_EXECUTORS) 314 template <
typename Allocator,
unsigned int Bits>
316 Allocator, Bits>::context() const ASIO_NOEXCEPT
321 template <
typename Allocator,
unsigned int Bits>
323 Bits>::on_work_started() const ASIO_NOEXCEPT
325 io_context_->impl_.work_started();
328 template <
typename Allocator,
unsigned int Bits>
330 Bits>::on_work_finished() const ASIO_NOEXCEPT
332 io_context_->impl_.work_finished();
335 template <
typename Allocator,
unsigned int Bits>
336 template <
typename Function,
typename OtherAllocator>
338 ASIO_MOVE_ARG(Function) f,
const OtherAllocator& a)
const 340 typedef typename decay<Function>::type function_type;
343 if (io_context_->impl_.can_dispatch())
346 function_type tmp(ASIO_MOVE_CAST(Function)(f));
349 asio_handler_invoke_helpers::invoke(tmp, tmp);
355 OtherAllocator, detail::operation> op;
356 typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
357 p.p =
new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);
359 ASIO_HANDLER_CREATION((*io_context_, *p.p,
360 "io_context", io_context_, 0,
"dispatch"));
362 io_context_->impl_.post_immediate_completion(p.p,
false);
366 template <
typename Allocator,
unsigned int Bits>
367 template <
typename Function,
typename OtherAllocator>
369 ASIO_MOVE_ARG(Function) f,
const OtherAllocator& a)
const 371 typedef typename decay<Function>::type function_type;
375 OtherAllocator, detail::operation> op;
376 typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
377 p.p =
new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);
379 ASIO_HANDLER_CREATION((*io_context_, *p.p,
380 "io_context", io_context_, 0,
"post"));
382 io_context_->impl_.post_immediate_completion(p.p,
false);
386 template <
typename Allocator,
unsigned int Bits>
387 template <
typename Function,
typename OtherAllocator>
389 ASIO_MOVE_ARG(Function) f,
const OtherAllocator& a)
const 391 typedef typename decay<Function>::type function_type;
395 OtherAllocator, detail::operation> op;
396 typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
397 p.p =
new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);
399 ASIO_HANDLER_CREATION((*io_context_, *p.p,
400 "io_context", io_context_, 0,
"defer"));
402 io_context_->impl_.post_immediate_completion(p.p,
true);
405 #endif // !defined(ASIO_NO_TS_EXECUTORS) 407 #if !defined(ASIO_NO_DEPRECATED) 409 : io_context_impl_(io_context.impl_)
411 io_context_impl_.work_started();
415 : io_context_impl_(other.io_context_impl_)
417 io_context_impl_.work_started();
422 io_context_impl_.work_finished();
429 #endif // !defined(ASIO_NO_DEPRECATED) 438 #include "asio/detail/pop_options.hpp" 440 #endif // ASIO_IMPL_IO_CONTEXT_HPP void defer(ASIO_MOVE_ARG(Function) f, const OtherAllocator &a) const
Request the io_context to invoke the given function object.
Definition: io_context.hpp:388
detail::wrapped_handler< io_context &, Handler > wrap(Handler handler)
(Deprecated: Use asio::bind_executor().) Create a new handler that automatically dispatches the wrapp...
Definition: io_context.hpp:210
post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
(Deprecated: Use asio::post().) Request the io_context to invoke the given handler and return immedia...
Definition: io_context.hpp:198
Definition: blocking.hpp:208
basic_executor_type< std::allocator< void >, 0 > executor_type
Executor used to submit functions to an io_context.
Definition: io_context.hpp:228
ASIO_INITFN_AUTO_RESULT_TYPE(RangeConnectHandler, void(asio::error_code, typename Protocol::endpoint)) async_connect(basic_socket< Protocol
Asynchronously establishes a socket connection by trying each endpoint in a sequence.
Provides core I/O functionality.
Definition: io_context.hpp:211
void dispatch(ASIO_MOVE_ARG(Function) f, const OtherAllocator &a) const
Request the io_context to invoke the given function object.
Definition: io_context.hpp:337
Definition: executor_op.hpp:31
Definition: non_const_lvalue.hpp:27
Executor implementation type used to submit functions to an io_context.
Definition: io_context.hpp:222
(Deprecated: Use executor_work_guard.) Class to inform the io_context when it has work to do...
Definition: io_context.hpp:1145
dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
(Deprecated: Use asio::dispatch().) Request the io_context to invoke the given handler.
Definition: io_context.hpp:159
void post(ASIO_MOVE_ARG(Function) f, const OtherAllocator &a) const
Request the io_context to invoke the given function object.
Definition: io_context.hpp:368
Definition: null_fenced_block.hpp:25
work(asio::io_context &io_context)
Constructor notifies the io_context that work is starting.
Definition: io_context.hpp:408
void reset()
(Deprecated: Use restart().) Reset the io_context in preparation for a subsequent run() invocation...
Definition: io_context.hpp:116
Class to represent an error code value.
Definition: error_code.hpp:80
basic_executor_type & operator=(const basic_executor_type &other) ASIO_NOEXCEPT
Assignment operator.
Definition: io_context.hpp:219
void execute(ASIO_MOVE_ARG(Function) f) const
Execution function.
Definition: io_context.hpp:266
Definition: io_context.hpp:121
asio::io_context & get_io_context()
Get the io_context object that owns the service.
Definition: io_context.hpp:431
executor_type get_executor() ASIO_NOEXCEPT
Obtains the executor associated with the io_context.
Definition: io_context.hpp:54
execution_context & context()
Get the context object that owns the service.
Definition: execution_context.hpp:100
~work()
Destructor notifies the io_context that the work is complete.
Definition: io_context.hpp:420
ASIO_DECL void restart()
Restart the io_context in preparation for a subsequent run() invocation.
Definition: io_context.ipp:129
Definition: wrapped_handler.hpp:48
Definition: io_context.hpp:165
Definition: any_io_executor.hpp:28
Definition: scheduler.hpp:38
Definition: completion_handler.hpp:31
asio::io_context & get_io_context()
Get the io_context associated with the work.
Definition: io_context.hpp:425