Chris@16: // Chris@16: // detail/task_io_service.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP Chris@16: #define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_ASIO_HAS_IOCP) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: struct task_io_service_thread_info; Chris@16: Chris@16: class task_io_service Chris@16: : public boost::asio::detail::service_base Chris@16: { Chris@16: public: Chris@16: typedef task_io_service_operation operation; Chris@16: Chris@16: // Constructor. Specifies the number of concurrent threads that are likely to Chris@16: // run the io_service. If set to 1 certain optimisation are performed. Chris@16: BOOST_ASIO_DECL task_io_service(boost::asio::io_service& io_service, Chris@16: std::size_t concurrency_hint = 0); Chris@16: Chris@16: // Destroy all user-defined handler objects owned by the service. Chris@16: BOOST_ASIO_DECL void shutdown_service(); Chris@16: Chris@16: // Initialise the task, if required. Chris@16: BOOST_ASIO_DECL void init_task(); Chris@16: Chris@16: // Run the event loop until interrupted or no more work. Chris@16: BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec); Chris@16: Chris@16: // Run until interrupted or one operation is performed. Chris@16: BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec); Chris@16: Chris@16: // Poll for operations without blocking. Chris@16: BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec); Chris@16: Chris@16: // Poll for one operation without blocking. Chris@16: BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec); Chris@16: Chris@16: // Interrupt the event processing loop. Chris@16: BOOST_ASIO_DECL void stop(); Chris@16: Chris@16: // Determine whether the io_service is stopped. Chris@16: BOOST_ASIO_DECL bool stopped() const; Chris@16: Chris@16: // Reset in preparation for a subsequent run invocation. Chris@16: BOOST_ASIO_DECL void reset(); Chris@16: Chris@16: // Notify that some work has started. Chris@16: void work_started() Chris@16: { Chris@16: ++outstanding_work_; Chris@16: } Chris@16: Chris@16: // Notify that some work has finished. Chris@16: void work_finished() Chris@16: { Chris@16: if (--outstanding_work_ == 0) Chris@16: stop(); Chris@16: } Chris@16: Chris@16: // Return whether a handler can be dispatched immediately. Chris@16: bool can_dispatch() Chris@16: { Chris@16: return thread_call_stack::contains(this) != 0; Chris@16: } Chris@16: Chris@16: // Request invocation of the given handler. Chris@16: template Chris@16: void dispatch(Handler& handler); Chris@16: Chris@16: // Request invocation of the given handler and return immediately. Chris@16: template Chris@16: void post(Handler& handler); Chris@16: Chris@16: // Request invocation of the given operation and return immediately. Assumes Chris@16: // that work_started() has not yet been called for the operation. Chris@16: BOOST_ASIO_DECL void post_immediate_completion( Chris@16: operation* op, bool is_continuation); Chris@16: Chris@16: // Request invocation of the given operation and return immediately. Assumes Chris@16: // that work_started() was previously called for the operation. Chris@16: BOOST_ASIO_DECL void post_deferred_completion(operation* op); Chris@16: Chris@16: // Request invocation of the given operations and return immediately. Assumes Chris@16: // that work_started() was previously called for each operation. Chris@16: BOOST_ASIO_DECL void post_deferred_completions(op_queue& ops); Chris@16: Chris@16: // Process unfinished operations as part of a shutdown_service operation. Chris@16: // Assumes that work_started() was previously called for the operations. Chris@16: BOOST_ASIO_DECL void abandon_operations(op_queue& ops); Chris@16: Chris@16: private: Chris@101: // Structure containing thread-specific data. Chris@16: typedef task_io_service_thread_info thread_info; Chris@16: Chris@16: // Enqueue the given operation following a failed attempt to dispatch the Chris@16: // operation for immediate invocation. Chris@16: BOOST_ASIO_DECL void do_dispatch(operation* op); Chris@16: Chris@16: // Run at most one operation. May block. Chris@16: BOOST_ASIO_DECL std::size_t do_run_one(mutex::scoped_lock& lock, Chris@16: thread_info& this_thread, const boost::system::error_code& ec); Chris@16: Chris@16: // Poll for at most one operation. Chris@16: BOOST_ASIO_DECL std::size_t do_poll_one(mutex::scoped_lock& lock, Chris@16: thread_info& this_thread, const boost::system::error_code& ec); Chris@16: Chris@16: // Stop the task and all idle threads. Chris@16: BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock); Chris@16: Chris@16: // Wake a single idle thread, or the task, and always unlock the mutex. Chris@16: BOOST_ASIO_DECL void wake_one_thread_and_unlock( Chris@16: mutex::scoped_lock& lock); Chris@16: Chris@16: // Helper class to perform task-related operations on block exit. Chris@16: struct task_cleanup; Chris@16: friend struct task_cleanup; Chris@16: Chris@16: // Helper class to call work-related operations on block exit. Chris@16: struct work_cleanup; Chris@16: friend struct work_cleanup; Chris@16: Chris@16: // Whether to optimise for single-threaded use cases. Chris@16: const bool one_thread_; Chris@16: Chris@16: // Mutex to protect access to internal data. Chris@16: mutable mutex mutex_; Chris@16: Chris@101: // Event to wake up blocked threads. Chris@101: event wakeup_event_; Chris@101: Chris@16: // The task to be run by this service. Chris@16: reactor* task_; Chris@16: Chris@16: // Operation object to represent the position of the task in the queue. Chris@16: struct task_operation : operation Chris@16: { Chris@16: task_operation() : operation(0) {} Chris@16: } task_operation_; Chris@16: Chris@16: // Whether the task has been interrupted. Chris@16: bool task_interrupted_; Chris@16: Chris@16: // The count of unfinished work. Chris@16: atomic_count outstanding_work_; Chris@16: Chris@16: // The queue of handlers that are ready to be delivered. Chris@16: op_queue op_queue_; Chris@16: Chris@16: // Flag to indicate that the dispatcher has been stopped. Chris@16: bool stopped_; Chris@16: Chris@16: // Flag to indicate that the dispatcher has been shut down. Chris@16: bool shutdown_; Chris@16: Chris@16: // Per-thread call stack to track the state of each thread in the io_service. Chris@16: typedef call_stack thread_call_stack; Chris@16: }; Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #if defined(BOOST_ASIO_HEADER_ONLY) Chris@16: # include Chris@16: #endif // defined(BOOST_ASIO_HEADER_ONLY) Chris@16: Chris@16: #endif // !defined(BOOST_ASIO_HAS_IOCP) Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP