Warning, file /include/boost/asio/detail/win_iocp_io_context.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_HPP
0012 #define BOOST_ASIO_DETAIL_WIN_IOCP_IO_CONTEXT_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
0022 #include <boost/asio/detail/limits.hpp>
0023 #include <boost/asio/detail/mutex.hpp>
0024 #include <boost/asio/detail/op_queue.hpp>
0025 #include <boost/asio/detail/scoped_ptr.hpp>
0026 #include <boost/asio/detail/socket_types.hpp>
0027 #include <boost/asio/detail/thread.hpp>
0028 #include <boost/asio/detail/thread_context.hpp>
0029 #include <boost/asio/detail/timer_queue_base.hpp>
0030 #include <boost/asio/detail/timer_queue_set.hpp>
0031 #include <boost/asio/detail/wait_op.hpp>
0032 #include <boost/asio/detail/win_iocp_operation.hpp>
0033 #include <boost/asio/detail/win_iocp_thread_info.hpp>
0034 #include <boost/asio/execution_context.hpp>
0035
0036 #include <boost/asio/detail/push_options.hpp>
0037
0038 namespace boost {
0039 namespace asio {
0040 namespace detail {
0041
0042 class wait_op;
0043
0044 class win_iocp_io_context
0045 : public execution_context_service_base<win_iocp_io_context>,
0046 public thread_context
0047 {
0048 public:
0049
0050 BOOST_ASIO_DECL win_iocp_io_context(
0051 boost::asio::execution_context& ctx, bool own_thread = true);
0052
0053
0054 BOOST_ASIO_DECL ~win_iocp_io_context();
0055
0056
0057 BOOST_ASIO_DECL void shutdown();
0058
0059
0060 void init_task()
0061 {
0062 }
0063
0064
0065 BOOST_ASIO_DECL boost::system::error_code register_handle(
0066 HANDLE handle, boost::system::error_code& ec);
0067
0068
0069 BOOST_ASIO_DECL size_t run(boost::system::error_code& ec);
0070
0071
0072 BOOST_ASIO_DECL size_t run_one(boost::system::error_code& ec);
0073
0074
0075 BOOST_ASIO_DECL size_t wait_one(long usec, boost::system::error_code& ec);
0076
0077
0078 BOOST_ASIO_DECL size_t poll(boost::system::error_code& ec);
0079
0080
0081 BOOST_ASIO_DECL size_t poll_one(boost::system::error_code& ec);
0082
0083
0084 BOOST_ASIO_DECL void stop();
0085
0086
0087 bool stopped() const
0088 {
0089 return ::InterlockedExchangeAdd(&stopped_, 0) != 0;
0090 }
0091
0092
0093 void restart()
0094 {
0095 ::InterlockedExchange(&stopped_, 0);
0096 }
0097
0098
0099 void work_started()
0100 {
0101 ::InterlockedIncrement(&outstanding_work_);
0102 }
0103
0104
0105 void work_finished()
0106 {
0107 if (::InterlockedDecrement(&outstanding_work_) == 0)
0108 stop();
0109 }
0110
0111
0112 BOOST_ASIO_DECL bool can_dispatch();
0113
0114
0115 BOOST_ASIO_DECL void capture_current_exception();
0116
0117
0118
0119 void post_immediate_completion(win_iocp_operation* op, bool)
0120 {
0121 work_started();
0122 post_deferred_completion(op);
0123 }
0124
0125
0126
0127 BOOST_ASIO_DECL void post_deferred_completion(win_iocp_operation* op);
0128
0129
0130
0131 BOOST_ASIO_DECL void post_deferred_completions(
0132 op_queue<win_iocp_operation>& ops);
0133
0134
0135
0136
0137 void post_private_immediate_completion(win_iocp_operation* op)
0138 {
0139 post_immediate_completion(op, false);
0140 }
0141
0142
0143
0144
0145 void post_private_deferred_completion(win_iocp_operation* op)
0146 {
0147 post_deferred_completion(op);
0148 }
0149
0150
0151
0152 void do_dispatch(operation* op)
0153 {
0154 post_immediate_completion(op, false);
0155 }
0156
0157
0158
0159 BOOST_ASIO_DECL void abandon_operations(op_queue<operation>& ops);
0160
0161
0162
0163
0164 BOOST_ASIO_DECL void on_pending(win_iocp_operation* op);
0165
0166
0167
0168
0169 BOOST_ASIO_DECL void on_completion(win_iocp_operation* op,
0170 DWORD last_error = 0, DWORD bytes_transferred = 0);
0171
0172
0173
0174
0175 BOOST_ASIO_DECL void on_completion(win_iocp_operation* op,
0176 const boost::system::error_code& ec, DWORD bytes_transferred = 0);
0177
0178
0179 template <typename Time_Traits>
0180 void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
0181
0182
0183 template <typename Time_Traits>
0184 void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
0185
0186
0187
0188 template <typename Time_Traits>
0189 void schedule_timer(timer_queue<Time_Traits>& queue,
0190 const typename Time_Traits::time_type& time,
0191 typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
0192
0193
0194
0195 template <typename Time_Traits>
0196 std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
0197 typename timer_queue<Time_Traits>::per_timer_data& timer,
0198 std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
0199
0200
0201 template <typename Time_Traits>
0202 void cancel_timer_by_key(timer_queue<Time_Traits>& queue,
0203 typename timer_queue<Time_Traits>::per_timer_data* timer,
0204 void* cancellation_key);
0205
0206
0207 template <typename Time_Traits>
0208 void move_timer(timer_queue<Time_Traits>& queue,
0209 typename timer_queue<Time_Traits>::per_timer_data& to,
0210 typename timer_queue<Time_Traits>::per_timer_data& from);
0211
0212 private:
0213 #if defined(WINVER) && (WINVER < 0x0500)
0214 typedef DWORD dword_ptr_t;
0215 typedef ULONG ulong_ptr_t;
0216 #else
0217 typedef DWORD_PTR dword_ptr_t;
0218 typedef ULONG_PTR ulong_ptr_t;
0219 #endif
0220
0221
0222
0223
0224 BOOST_ASIO_DECL size_t do_one(DWORD msec,
0225 win_iocp_thread_info& this_thread, boost::system::error_code& ec);
0226
0227
0228 BOOST_ASIO_DECL static DWORD get_gqcs_timeout();
0229
0230
0231 BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
0232
0233
0234 BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
0235
0236
0237 BOOST_ASIO_DECL void update_timeout();
0238
0239
0240 struct work_finished_on_block_exit;
0241
0242
0243 struct auto_handle
0244 {
0245 HANDLE handle;
0246 auto_handle() : handle(0) {}
0247 ~auto_handle() { if (handle) ::CloseHandle(handle); }
0248 };
0249
0250
0251 auto_handle iocp_;
0252
0253
0254 long outstanding_work_;
0255
0256
0257 mutable long stopped_;
0258
0259
0260
0261
0262 long stop_event_posted_;
0263
0264
0265 long shutdown_;
0266
0267 enum
0268 {
0269 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
0270
0271
0272
0273
0274 default_gqcs_timeout = 500,
0275 #endif
0276
0277
0278 max_timeout_msec = 5 * 60 * 1000,
0279
0280
0281 max_timeout_usec = max_timeout_msec * 1000,
0282
0283
0284
0285 wake_for_dispatch = 1,
0286
0287
0288
0289
0290 overlapped_contains_result = 2
0291 };
0292
0293
0294 const DWORD gqcs_timeout_;
0295
0296
0297 struct thread_function;
0298 friend struct thread_function;
0299
0300
0301 struct timer_thread_function;
0302 friend struct timer_thread_function;
0303
0304
0305 scoped_ptr<thread> timer_thread_;
0306
0307
0308 auto_handle waitable_timer_;
0309
0310
0311 long dispatch_required_;
0312
0313
0314 mutex dispatch_mutex_;
0315
0316
0317 timer_queue_set timer_queues_;
0318
0319
0320 op_queue<win_iocp_operation> completed_ops_;
0321
0322
0323 const int concurrency_hint_;
0324
0325
0326 scoped_ptr<thread> thread_;
0327 };
0328
0329 }
0330 }
0331 }
0332
0333 #include <boost/asio/detail/pop_options.hpp>
0334
0335 #include <boost/asio/detail/impl/win_iocp_io_context.hpp>
0336 #if defined(BOOST_ASIO_HEADER_ONLY)
0337 # include <boost/asio/detail/impl/win_iocp_io_context.ipp>
0338 #endif
0339
0340 #endif
0341
0342 #endif