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