1 // 2 // detail/select_reactor.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 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 ASIO_DETAIL_SELECT_REACTOR_HPP 12 #define ASIO_DETAIL_SELECT_REACTOR_HPP 13 14 15 #include "asio/detail/config.hpp" 16 17 #if defined(ASIO_HAS_IOCP) || (!defined(ASIO_HAS_DEV_POLL) && !defined(ASIO_HAS_EPOLL) && !defined(ASIO_HAS_KQUEUE) && !defined(ASIO_WINDOWS_RUNTIME)) 18 19 #include <cstddef> 20 #include "asio/detail/fd_set_adapter.hpp" 21 #include "asio/detail/limits.hpp" 22 #include "asio/detail/mutex.hpp" 23 #include "asio/detail/op_queue.hpp" 24 #include "asio/detail/reactor_op.hpp" 25 #include "asio/detail/reactor_op_queue.hpp" 26 #include "asio/detail/select_interrupter.hpp" 27 #include "asio/detail/socket_types.hpp" 28 #include "asio/detail/timer_queue_base.hpp" 29 #include "asio/detail/timer_queue_set.hpp" 30 #include "asio/detail/wait_op.hpp" 31 #include "asio/io_service.hpp" 32 33 34 #include "asio/detail/push_options.hpp" 35 36 namespace asio { 37 namespace detail { 38 39 class select_reactor 40 : public asio::detail::service_base<select_reactor> 41 { 42 public: 43 enum op_types { read_op = 0, write_op = 1, except_op = 2, 44 max_select_ops = 3, connect_op = 1, max_ops = 3 }; 45 46 // Per-descriptor data. 47 struct per_descriptor_data 48 { 49 }; 50 51 // Constructor. 52 ASIO_DECL select_reactor(asio::io_service& io_service); 53 54 // Destructor. 55 ASIO_DECL ~select_reactor(); 56 57 // Destroy all user-defined handler objects owned by the service. 58 ASIO_DECL void shutdown_service(); 59 60 // Recreate internal descriptors following a fork. 61 ASIO_DECL void fork_service( 62 asio::io_service::fork_event fork_ev); 63 64 // Initialise the task, but only if the reactor is not in its own thread. 65 ASIO_DECL void init_task(); 66 67 // Register a socket with the reactor. Returns 0 on success, system error 68 // code on failure. 69 ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&); 70 71 // Register a descriptor with an associated single operation. Returns 0 on 72 // success, system error code on failure. 73 ASIO_DECL int register_internal_descriptor( 74 int op_type, socket_type descriptor, 75 per_descriptor_data& descriptor_data, reactor_op* op); 76 77 // Post a reactor operation for immediate completion. post_immediate_completion(reactor_op * op,bool is_continuation)78 void post_immediate_completion(reactor_op* op, bool is_continuation) 79 { 80 io_service_.post_immediate_completion(op, is_continuation); 81 } 82 83 // Start a new operation. The reactor operation will be performed when the 84 // given descriptor is flagged as ready, or an error has occurred. 85 ASIO_DECL void start_op(int op_type, socket_type descriptor, 86 per_descriptor_data&, reactor_op* op, bool is_continuation, bool); 87 88 // Cancel all operations associated with the given descriptor. The 89 // handlers associated with the descriptor will be invoked with the 90 // operation_aborted error. 91 ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&); 92 93 // Cancel any operations that are running against the descriptor and remove 94 // its registration from the reactor. 95 ASIO_DECL void deregister_descriptor(socket_type descriptor, 96 per_descriptor_data&, bool closing); 97 98 // Remote the descriptor's registration from the reactor. 99 ASIO_DECL void deregister_internal_descriptor( 100 socket_type descriptor, per_descriptor_data& descriptor_data); 101 102 // Move descriptor registration from one descriptor_data object to another. 103 ASIO_DECL void move_descriptor(socket_type descriptor, 104 per_descriptor_data& target_descriptor_data, 105 per_descriptor_data& source_descriptor_data); 106 107 // Add a new timer queue to the reactor. 108 template <typename Time_Traits> 109 void add_timer_queue(timer_queue<Time_Traits>& queue); 110 111 // Remove a timer queue from the reactor. 112 template <typename Time_Traits> 113 void remove_timer_queue(timer_queue<Time_Traits>& queue); 114 115 // Schedule a new operation in the given timer queue to expire at the 116 // specified absolute time. 117 template <typename Time_Traits> 118 void schedule_timer(timer_queue<Time_Traits>& queue, 119 const typename Time_Traits::time_type& time, 120 typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); 121 122 // Cancel the timer operations associated with the given token. Returns the 123 // number of operations that have been posted or dispatched. 124 template <typename Time_Traits> 125 std::size_t cancel_timer(timer_queue<Time_Traits>& queue, 126 typename timer_queue<Time_Traits>::per_timer_data& timer, 127 std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); 128 129 // Run select once until interrupted or events are ready to be dispatched. 130 ASIO_DECL void run(bool block, op_queue<operation>& ops); 131 132 // Interrupt the select loop. 133 ASIO_DECL void interrupt(); 134 135 private: 136 137 // Helper function to add a new timer queue. 138 ASIO_DECL void do_add_timer_queue(timer_queue_base& queue); 139 140 // Helper function to remove a timer queue. 141 ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue); 142 143 // Get the timeout value for the select call. 144 ASIO_DECL timeval* get_timeout(timeval& tv); 145 146 // Cancel all operations associated with the given descriptor. This function 147 // does not acquire the select_reactor's mutex. 148 ASIO_DECL void cancel_ops_unlocked(socket_type descriptor, 149 const asio::error_code& ec); 150 151 // The io_service implementation used to post completions. 152 io_service_impl& io_service_; 153 154 // Mutex to protect access to internal data. 155 asio::detail::mutex mutex_; 156 157 // The interrupter is used to break a blocking select call. 158 select_interrupter interrupter_; 159 160 // The queues of read, write and except operations. 161 reactor_op_queue<socket_type> op_queue_[max_ops]; 162 163 // The file descriptor sets to be passed to the select system call. 164 fd_set_adapter fd_sets_[max_select_ops]; 165 166 // The timer queues. 167 timer_queue_set timer_queues_; 168 169 170 // Whether the service has been shut down. 171 bool shutdown_; 172 }; 173 174 } // namespace detail 175 } // namespace asio 176 177 #include "asio/detail/pop_options.hpp" 178 179 #include "asio/detail/impl/select_reactor.hpp" 180 # include "asio/detail/impl/select_reactor.ipp" 181 182 #endif // defined(ASIO_HAS_IOCP) 183 // || (!defined(ASIO_HAS_DEV_POLL) 184 // && !defined(ASIO_HAS_EPOLL) 185 // && !defined(ASIO_HAS_KQUEUE) 186 // && !defined(ASIO_WINDOWS_RUNTIME)) 187 188 #endif // ASIO_DETAIL_SELECT_REACTOR_HPP 189