File indexing completed on 2025-01-18 09:28:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP
0012 #define BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_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_WINDOWS_RUNTIME)
0021
0022 #include <boost/asio/buffer.hpp>
0023 #include <boost/asio/error.hpp>
0024 #include <boost/asio/execution_context.hpp>
0025 #include <boost/asio/socket_base.hpp>
0026 #include <boost/asio/detail/buffer_sequence_adapter.hpp>
0027 #include <boost/asio/detail/memory.hpp>
0028 #include <boost/asio/detail/socket_types.hpp>
0029 #include <boost/asio/detail/winrt_async_manager.hpp>
0030 #include <boost/asio/detail/winrt_socket_recv_op.hpp>
0031 #include <boost/asio/detail/winrt_socket_send_op.hpp>
0032
0033 #if defined(BOOST_ASIO_HAS_IOCP)
0034 # include <boost/asio/detail/win_iocp_io_context.hpp>
0035 #else
0036 # include <boost/asio/detail/scheduler.hpp>
0037 #endif
0038
0039 #include <boost/asio/detail/push_options.hpp>
0040
0041 namespace boost {
0042 namespace asio {
0043 namespace detail {
0044
0045 class winrt_ssocket_service_base
0046 {
0047 public:
0048
0049 typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type;
0050
0051
0052 struct base_implementation_type
0053 {
0054
0055 base_implementation_type()
0056 : socket_(nullptr),
0057 next_(0),
0058 prev_(0)
0059 {
0060 }
0061
0062
0063 native_handle_type socket_;
0064
0065
0066 base_implementation_type* next_;
0067 base_implementation_type* prev_;
0068 };
0069
0070
0071 BOOST_ASIO_DECL winrt_ssocket_service_base(execution_context& context);
0072
0073
0074 BOOST_ASIO_DECL void base_shutdown();
0075
0076
0077 BOOST_ASIO_DECL void construct(base_implementation_type&);
0078
0079
0080 BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
0081 base_implementation_type& other_impl) noexcept;
0082
0083
0084 BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl,
0085 winrt_ssocket_service_base& other_service,
0086 base_implementation_type& other_impl);
0087
0088
0089 BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
0090
0091
0092 bool is_open(const base_implementation_type& impl) const
0093 {
0094 return impl.socket_ != nullptr;
0095 }
0096
0097
0098 BOOST_ASIO_DECL boost::system::error_code close(
0099 base_implementation_type& impl, boost::system::error_code& ec);
0100
0101
0102 BOOST_ASIO_DECL native_handle_type release(
0103 base_implementation_type& impl, boost::system::error_code& ec);
0104
0105
0106 native_handle_type native_handle(base_implementation_type& impl)
0107 {
0108 return impl.socket_;
0109 }
0110
0111
0112 boost::system::error_code cancel(base_implementation_type&,
0113 boost::system::error_code& ec)
0114 {
0115 ec = boost::asio::error::operation_not_supported;
0116 return ec;
0117 }
0118
0119
0120 bool at_mark(const base_implementation_type&,
0121 boost::system::error_code& ec) const
0122 {
0123 ec = boost::asio::error::operation_not_supported;
0124 return false;
0125 }
0126
0127
0128 std::size_t available(const base_implementation_type&,
0129 boost::system::error_code& ec) const
0130 {
0131 ec = boost::asio::error::operation_not_supported;
0132 return 0;
0133 }
0134
0135
0136 template <typename IO_Control_Command>
0137 boost::system::error_code io_control(base_implementation_type&,
0138 IO_Control_Command&, boost::system::error_code& ec)
0139 {
0140 ec = boost::asio::error::operation_not_supported;
0141 return ec;
0142 }
0143
0144
0145 bool non_blocking(const base_implementation_type&) const
0146 {
0147 return false;
0148 }
0149
0150
0151 boost::system::error_code non_blocking(base_implementation_type&,
0152 bool, boost::system::error_code& ec)
0153 {
0154 ec = boost::asio::error::operation_not_supported;
0155 return ec;
0156 }
0157
0158
0159 bool native_non_blocking(const base_implementation_type&) const
0160 {
0161 return false;
0162 }
0163
0164
0165 boost::system::error_code native_non_blocking(base_implementation_type&,
0166 bool, boost::system::error_code& ec)
0167 {
0168 ec = boost::asio::error::operation_not_supported;
0169 return ec;
0170 }
0171
0172
0173 template <typename ConstBufferSequence>
0174 std::size_t send(base_implementation_type& impl,
0175 const ConstBufferSequence& buffers,
0176 socket_base::message_flags flags, boost::system::error_code& ec)
0177 {
0178 return do_send(impl,
0179 buffer_sequence_adapter<boost::asio::const_buffer,
0180 ConstBufferSequence>::first(buffers), flags, ec);
0181 }
0182
0183
0184 std::size_t send(base_implementation_type&, const null_buffers&,
0185 socket_base::message_flags, boost::system::error_code& ec)
0186 {
0187 ec = boost::asio::error::operation_not_supported;
0188 return 0;
0189 }
0190
0191
0192
0193 template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
0194 void async_send(base_implementation_type& impl,
0195 const ConstBufferSequence& buffers, socket_base::message_flags flags,
0196 Handler& handler, const IoExecutor& io_ex)
0197 {
0198 bool is_continuation =
0199 boost_asio_handler_cont_helpers::is_continuation(handler);
0200
0201
0202 typedef winrt_socket_send_op<ConstBufferSequence, Handler, IoExecutor> op;
0203 typename op::ptr p = { boost::asio::detail::addressof(handler),
0204 op::ptr::allocate(handler), 0 };
0205 p.p = new (p.v) op(buffers, handler, io_ex);
0206
0207 BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
0208 *p.p, "socket", &impl, 0, "async_send"));
0209
0210 start_send_op(impl,
0211 buffer_sequence_adapter<boost::asio::const_buffer,
0212 ConstBufferSequence>::first(buffers),
0213 flags, p.p, is_continuation);
0214 p.v = p.p = 0;
0215 }
0216
0217
0218 template <typename Handler, typename IoExecutor>
0219 void async_send(base_implementation_type&, const null_buffers&,
0220 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
0221 {
0222 boost::system::error_code ec = boost::asio::error::operation_not_supported;
0223 const std::size_t bytes_transferred = 0;
0224 boost::asio::post(io_ex,
0225 detail::bind_handler(handler, ec, bytes_transferred));
0226 }
0227
0228
0229 template <typename MutableBufferSequence>
0230 std::size_t receive(base_implementation_type& impl,
0231 const MutableBufferSequence& buffers,
0232 socket_base::message_flags flags, boost::system::error_code& ec)
0233 {
0234 return do_receive(impl,
0235 buffer_sequence_adapter<boost::asio::mutable_buffer,
0236 MutableBufferSequence>::first(buffers), flags, ec);
0237 }
0238
0239
0240 std::size_t receive(base_implementation_type&, const null_buffers&,
0241 socket_base::message_flags, boost::system::error_code& ec)
0242 {
0243 ec = boost::asio::error::operation_not_supported;
0244 return 0;
0245 }
0246
0247
0248
0249 template <typename MutableBufferSequence,
0250 typename Handler, typename IoExecutor>
0251 void async_receive(base_implementation_type& impl,
0252 const MutableBufferSequence& buffers, socket_base::message_flags flags,
0253 Handler& handler, const IoExecutor& io_ex)
0254 {
0255 bool is_continuation =
0256 boost_asio_handler_cont_helpers::is_continuation(handler);
0257
0258
0259 typedef winrt_socket_recv_op<MutableBufferSequence, Handler, IoExecutor> op;
0260 typename op::ptr p = { boost::asio::detail::addressof(handler),
0261 op::ptr::allocate(handler), 0 };
0262 p.p = new (p.v) op(buffers, handler, io_ex);
0263
0264 BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
0265 *p.p, "socket", &impl, 0, "async_receive"));
0266
0267 start_receive_op(impl,
0268 buffer_sequence_adapter<boost::asio::mutable_buffer,
0269 MutableBufferSequence>::first(buffers),
0270 flags, p.p, is_continuation);
0271 p.v = p.p = 0;
0272 }
0273
0274
0275 template <typename Handler, typename IoExecutor>
0276 void async_receive(base_implementation_type&, const null_buffers&,
0277 socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
0278 {
0279 boost::system::error_code ec = boost::asio::error::operation_not_supported;
0280 const std::size_t bytes_transferred = 0;
0281 boost::asio::post(io_ex,
0282 detail::bind_handler(handler, ec, bytes_transferred));
0283 }
0284
0285 protected:
0286
0287 BOOST_ASIO_DECL std::size_t do_get_endpoint(
0288 const base_implementation_type& impl, bool local,
0289 void* addr, std::size_t addr_len, boost::system::error_code& ec) const;
0290
0291
0292 BOOST_ASIO_DECL boost::system::error_code do_set_option(
0293 base_implementation_type& impl,
0294 int level, int optname, const void* optval,
0295 std::size_t optlen, boost::system::error_code& ec);
0296
0297
0298 BOOST_ASIO_DECL void do_get_option(
0299 const base_implementation_type& impl,
0300 int level, int optname, void* optval,
0301 std::size_t* optlen, boost::system::error_code& ec) const;
0302
0303
0304 BOOST_ASIO_DECL boost::system::error_code do_connect(
0305 base_implementation_type& impl,
0306 const void* addr, boost::system::error_code& ec);
0307
0308
0309 BOOST_ASIO_DECL void start_connect_op(
0310 base_implementation_type& impl, const void* addr,
0311 winrt_async_op<void>* op, bool is_continuation);
0312
0313
0314 BOOST_ASIO_DECL std::size_t do_send(
0315 base_implementation_type& impl, const boost::asio::const_buffer& data,
0316 socket_base::message_flags flags, boost::system::error_code& ec);
0317
0318
0319 BOOST_ASIO_DECL void start_send_op(base_implementation_type& impl,
0320 const boost::asio::const_buffer& data, socket_base::message_flags flags,
0321 winrt_async_op<unsigned int>* op, bool is_continuation);
0322
0323
0324 BOOST_ASIO_DECL std::size_t do_receive(
0325 base_implementation_type& impl, const boost::asio::mutable_buffer& data,
0326 socket_base::message_flags flags, boost::system::error_code& ec);
0327
0328
0329 BOOST_ASIO_DECL void start_receive_op(base_implementation_type& impl,
0330 const boost::asio::mutable_buffer& data, socket_base::message_flags flags,
0331 winrt_async_op<Windows::Storage::Streams::IBuffer^>* op,
0332 bool is_continuation);
0333
0334
0335 #if defined(BOOST_ASIO_HAS_IOCP)
0336 typedef class win_iocp_io_context scheduler_impl;
0337 #else
0338 typedef class scheduler scheduler_impl;
0339 #endif
0340 scheduler_impl& scheduler_;
0341
0342
0343 winrt_async_manager& async_manager_;
0344
0345
0346 boost::asio::detail::mutex mutex_;
0347
0348
0349 base_implementation_type* impl_list_;
0350 };
0351
0352 }
0353 }
0354 }
0355
0356 #include <boost/asio/detail/pop_options.hpp>
0357
0358 #if defined(BOOST_ASIO_HEADER_ONLY)
0359 # include <boost/asio/detail/impl/winrt_ssocket_service_base.ipp>
0360 #endif
0361
0362 #endif
0363
0364 #endif