File indexing completed on 2025-01-18 09:28:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP
0012 #define BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019
0020 #if defined(BOOST_ASIO_HAS_IOCP) \
0021 || (!defined(BOOST_ASIO_HAS_DEV_POLL) \
0022 && !defined(BOOST_ASIO_HAS_EPOLL) \
0023 && !defined(BOOST_ASIO_HAS_KQUEUE) \
0024 && !defined(BOOST_ASIO_WINDOWS_RUNTIME))
0025
0026 #include <cstddef>
0027 #include <boost/asio/detail/fd_set_adapter.hpp>
0028 #include <boost/asio/detail/limits.hpp>
0029 #include <boost/asio/detail/mutex.hpp>
0030 #include <boost/asio/detail/op_queue.hpp>
0031 #include <boost/asio/detail/reactor_op.hpp>
0032 #include <boost/asio/detail/reactor_op_queue.hpp>
0033 #include <boost/asio/detail/scheduler_task.hpp>
0034 #include <boost/asio/detail/select_interrupter.hpp>
0035 #include <boost/asio/detail/socket_types.hpp>
0036 #include <boost/asio/detail/timer_queue_base.hpp>
0037 #include <boost/asio/detail/timer_queue_set.hpp>
0038 #include <boost/asio/detail/wait_op.hpp>
0039 #include <boost/asio/execution_context.hpp>
0040
0041 #if defined(BOOST_ASIO_HAS_IOCP)
0042 # include <boost/asio/detail/thread.hpp>
0043 #endif
0044
0045 #include <boost/asio/detail/push_options.hpp>
0046
0047 namespace boost {
0048 namespace asio {
0049 namespace detail {
0050
0051 class select_reactor
0052 : public execution_context_service_base<select_reactor>
0053 #if !defined(BOOST_ASIO_HAS_IOCP)
0054 , public scheduler_task
0055 #endif
0056 {
0057 public:
0058 #if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
0059 enum op_types { read_op = 0, write_op = 1, except_op = 2,
0060 max_select_ops = 3, connect_op = 3, max_ops = 4 };
0061 #else
0062 enum op_types { read_op = 0, write_op = 1, except_op = 2,
0063 max_select_ops = 3, connect_op = 1, max_ops = 3 };
0064 #endif
0065
0066
0067 struct per_descriptor_data
0068 {
0069 };
0070
0071
0072 BOOST_ASIO_DECL select_reactor(boost::asio::execution_context& ctx);
0073
0074
0075 BOOST_ASIO_DECL ~select_reactor();
0076
0077
0078 BOOST_ASIO_DECL void shutdown();
0079
0080
0081 BOOST_ASIO_DECL void notify_fork(
0082 boost::asio::execution_context::fork_event fork_ev);
0083
0084
0085 BOOST_ASIO_DECL void init_task();
0086
0087
0088
0089 BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&);
0090
0091
0092
0093 BOOST_ASIO_DECL int register_internal_descriptor(
0094 int op_type, socket_type descriptor,
0095 per_descriptor_data& descriptor_data, reactor_op* op);
0096
0097
0098 void post_immediate_completion(operation* op, bool is_continuation) const;
0099
0100
0101 BOOST_ASIO_DECL static void call_post_immediate_completion(
0102 operation* op, bool is_continuation, const void* self);
0103
0104
0105
0106 BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
0107 per_descriptor_data&, reactor_op* op, bool is_continuation, bool,
0108 void (*on_immediate)(operation*, bool, const void*),
0109 const void* immediate_arg);
0110
0111
0112
0113 void start_op(int op_type, socket_type descriptor,
0114 per_descriptor_data& descriptor_data, reactor_op* op,
0115 bool is_continuation, bool allow_speculative)
0116 {
0117 start_op(op_type, descriptor, descriptor_data,
0118 op, is_continuation, allow_speculative,
0119 &select_reactor::call_post_immediate_completion, this);
0120 }
0121
0122
0123
0124
0125 BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
0126
0127
0128
0129
0130 BOOST_ASIO_DECL void cancel_ops_by_key(socket_type descriptor,
0131 per_descriptor_data& descriptor_data,
0132 int op_type, void* cancellation_key);
0133
0134
0135
0136
0137 BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
0138 per_descriptor_data&, bool closing);
0139
0140
0141
0142
0143 BOOST_ASIO_DECL void deregister_internal_descriptor(
0144 socket_type descriptor, per_descriptor_data&);
0145
0146
0147
0148 BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
0149
0150
0151 BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
0152 per_descriptor_data& target_descriptor_data,
0153 per_descriptor_data& source_descriptor_data);
0154
0155
0156 template <typename Time_Traits>
0157 void add_timer_queue(timer_queue<Time_Traits>& queue);
0158
0159
0160 template <typename Time_Traits>
0161 void remove_timer_queue(timer_queue<Time_Traits>& queue);
0162
0163
0164
0165 template <typename Time_Traits>
0166 void schedule_timer(timer_queue<Time_Traits>& queue,
0167 const typename Time_Traits::time_type& time,
0168 typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
0169
0170
0171
0172 template <typename Time_Traits>
0173 std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
0174 typename timer_queue<Time_Traits>::per_timer_data& timer,
0175 std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
0176
0177
0178 template <typename Time_Traits>
0179 void cancel_timer_by_key(timer_queue<Time_Traits>& queue,
0180 typename timer_queue<Time_Traits>::per_timer_data* timer,
0181 void* cancellation_key);
0182
0183
0184 template <typename Time_Traits>
0185 void move_timer(timer_queue<Time_Traits>& queue,
0186 typename timer_queue<Time_Traits>::per_timer_data& target,
0187 typename timer_queue<Time_Traits>::per_timer_data& source);
0188
0189
0190 BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
0191
0192
0193 BOOST_ASIO_DECL void interrupt();
0194
0195 private:
0196 #if defined(BOOST_ASIO_HAS_IOCP)
0197
0198 BOOST_ASIO_DECL void run_thread();
0199 #endif
0200
0201
0202 BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
0203
0204
0205 BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
0206
0207
0208 BOOST_ASIO_DECL timeval* get_timeout(long usec, timeval& tv);
0209
0210
0211
0212 BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor,
0213 const boost::system::error_code& ec);
0214
0215
0216 # if defined(BOOST_ASIO_HAS_IOCP)
0217 typedef class win_iocp_io_context scheduler_type;
0218 # else
0219 typedef class scheduler scheduler_type;
0220 # endif
0221 scheduler_type& scheduler_;
0222
0223
0224 boost::asio::detail::mutex mutex_;
0225
0226
0227 select_interrupter interrupter_;
0228
0229
0230 reactor_op_queue<socket_type> op_queue_[max_ops];
0231
0232
0233 fd_set_adapter fd_sets_[max_select_ops];
0234
0235
0236 timer_queue_set timer_queues_;
0237
0238 #if defined(BOOST_ASIO_HAS_IOCP)
0239
0240 class thread_function;
0241 friend class thread_function;
0242
0243
0244 bool stop_thread_;
0245
0246
0247 boost::asio::detail::thread* thread_;
0248
0249
0250 class restart_reactor : public operation
0251 {
0252 public:
0253 restart_reactor(select_reactor* r)
0254 : operation(&restart_reactor::do_complete),
0255 reactor_(r)
0256 {
0257 }
0258
0259 BOOST_ASIO_DECL static void do_complete(void* owner, operation* base,
0260 const boost::system::error_code& ec, std::size_t bytes_transferred);
0261
0262 private:
0263 select_reactor* reactor_;
0264 };
0265
0266 friend class restart_reactor;
0267
0268
0269 restart_reactor restart_reactor_;
0270 #endif
0271
0272
0273 bool shutdown_;
0274 };
0275
0276 }
0277 }
0278 }
0279
0280 #include <boost/asio/detail/pop_options.hpp>
0281
0282 #include <boost/asio/detail/impl/select_reactor.hpp>
0283 #if defined(BOOST_ASIO_HEADER_ONLY)
0284 # include <boost/asio/detail/impl/select_reactor.ipp>
0285 #endif
0286
0287 #endif
0288
0289
0290
0291
0292
0293 #endif