Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:48

0001 //
0002 // detail/winrt_ssocket_service_base.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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 // defined(BOOST_ASIO_HAS_IOCP)
0036 # include <boost/asio/detail/scheduler.hpp>
0037 #endif // defined(BOOST_ASIO_HAS_IOCP)
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   // The native type of a socket.
0049   typedef Windows::Networking::Sockets::StreamSocket^ native_handle_type;
0050 
0051   // The implementation type of the socket.
0052   struct base_implementation_type
0053   {
0054     // Default constructor.
0055     base_implementation_type()
0056       : socket_(nullptr),
0057         next_(0),
0058         prev_(0)
0059     {
0060     }
0061 
0062     // The underlying native socket.
0063     native_handle_type socket_;
0064 
0065     // Pointers to adjacent socket implementations in linked list.
0066     base_implementation_type* next_;
0067     base_implementation_type* prev_;
0068   };
0069 
0070   // Constructor.
0071   BOOST_ASIO_DECL winrt_ssocket_service_base(execution_context& context);
0072 
0073   // Destroy all user-defined handler objects owned by the service.
0074   BOOST_ASIO_DECL void base_shutdown();
0075 
0076   // Construct a new socket implementation.
0077   BOOST_ASIO_DECL void construct(base_implementation_type&);
0078 
0079   // Move-construct a new socket implementation.
0080   BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl,
0081       base_implementation_type& other_impl) noexcept;
0082 
0083   // Move-assign from another socket implementation.
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   // Destroy a socket implementation.
0089   BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
0090 
0091   // Determine whether the socket is open.
0092   bool is_open(const base_implementation_type& impl) const
0093   {
0094     return impl.socket_ != nullptr;
0095   }
0096 
0097   // Destroy a socket implementation.
0098   BOOST_ASIO_DECL boost::system::error_code close(
0099       base_implementation_type& impl, boost::system::error_code& ec);
0100 
0101   // Release ownership of the socket.
0102   BOOST_ASIO_DECL native_handle_type release(
0103       base_implementation_type& impl, boost::system::error_code& ec);
0104 
0105   // Get the native socket representation.
0106   native_handle_type native_handle(base_implementation_type& impl)
0107   {
0108     return impl.socket_;
0109   }
0110 
0111   // Cancel all operations associated with the socket.
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   // Determine whether the socket is at the out-of-band data mark.
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   // Determine the number of bytes available for reading.
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   // Perform an IO control command on the socket.
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   // Gets the non-blocking mode of the socket.
0145   bool non_blocking(const base_implementation_type&) const
0146   {
0147     return false;
0148   }
0149 
0150   // Sets the non-blocking mode of the socket.
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   // Gets the non-blocking mode of the native socket implementation.
0159   bool native_non_blocking(const base_implementation_type&) const
0160   {
0161     return false;
0162   }
0163 
0164   // Sets the non-blocking mode of the native socket implementation.
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   // Send the given data to the peer.
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   // Wait until data can be sent without blocking.
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   // Start an asynchronous send. The data being sent must be valid for the
0192   // lifetime of the asynchronous operation.
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     // Allocate and construct an operation to wrap the handler.
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   // Start an asynchronous wait until data can be sent without blocking.
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   // Receive some data from the peer. Returns the number of bytes received.
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   // Wait until data can be received without blocking.
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   // Start an asynchronous receive. The buffer for the data being received
0248   // must be valid for the lifetime of the asynchronous operation.
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     // Allocate and construct an operation to wrap the handler.
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   // Wait until data can be received without blocking.
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   // Helper function to obtain endpoints associated with the connection.
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   // Helper function to set a socket option.
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   // Helper function to get a socket option.
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   // Helper function to perform a synchronous connect.
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   // Helper function to start an asynchronous connect.
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   // Helper function to perform a synchronous send.
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   // Helper function to start an asynchronous send.
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   // Helper function to perform a synchronous receive.
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   // Helper function to start an asynchronous receive.
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   // The scheduler implementation used for delivering completions.
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   // The manager that keeps track of outstanding operations.
0343   winrt_async_manager& async_manager_;
0344 
0345   // Mutex to protect access to the linked list of implementations. 
0346   boost::asio::detail::mutex mutex_;
0347 
0348   // The head of a linked list of all implementations.
0349   base_implementation_type* impl_list_;
0350 };
0351 
0352 } // namespace detail
0353 } // namespace asio
0354 } // namespace boost
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 // defined(BOOST_ASIO_HEADER_ONLY)
0361 
0362 #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
0363 
0364 #endif // BOOST_ASIO_DETAIL_WINRT_SSOCKET_SERVICE_BASE_HPP