⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win_iocp_socket_service.hpp

📁 这是国外的resip协议栈
💻 HPP
📖 第 1 页 / 共 5 页
字号:
//// win_iocp_socket_service.hpp// ~~~~~~~~~~~~~~~~~~~~~~~~~~~//// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//#ifndef ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP#define ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)#include "asio/detail/push_options.hpp"#include "asio/detail/win_iocp_io_service_fwd.hpp"#if defined(ASIO_HAS_IOCP)#include "asio/detail/push_options.hpp"#include <cstring>#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>#include "asio/detail/pop_options.hpp"#include "asio/buffer.hpp"#include "asio/error.hpp"#include "asio/io_service.hpp"#include "asio/socket_base.hpp"#include "asio/detail/bind_handler.hpp"#include "asio/detail/handler_alloc_helpers.hpp"#include "asio/detail/handler_invoke_helpers.hpp"#include "asio/detail/mutex.hpp"#include "asio/detail/select_reactor.hpp"#include "asio/detail/socket_holder.hpp"#include "asio/detail/socket_ops.hpp"#include "asio/detail/socket_types.hpp"#include "asio/detail/win_iocp_io_service.hpp"namespace asio {namespace detail {template <typename Protocol>class win_iocp_socket_service  : public asio::detail::service_base<win_iocp_socket_service<Protocol> >{public:  // The protocol type.  typedef Protocol protocol_type;  // The endpoint type.  typedef typename Protocol::endpoint endpoint_type;  // Base class for all operations.  typedef win_iocp_operation operation;  struct noop_deleter { void operator()(void*) {} };  typedef boost::shared_ptr<void> shared_cancel_token_type;  typedef boost::weak_ptr<void> weak_cancel_token_type;  // The native type of a socket.  class native_type  {  public:    native_type(socket_type s)      : socket_(s),        have_remote_endpoint_(false)    {    }    native_type(socket_type s, const endpoint_type& ep)      : socket_(s),        have_remote_endpoint_(true),        remote_endpoint_(ep)    {    }    void operator=(socket_type s)    {      socket_ = s;      have_remote_endpoint_ = false;      remote_endpoint_ = endpoint_type();    }    operator socket_type() const    {      return socket_;    }    HANDLE as_handle() const    {      return reinterpret_cast<HANDLE>(socket_);    }    bool have_remote_endpoint() const    {      return have_remote_endpoint_;    }    endpoint_type remote_endpoint() const    {      return remote_endpoint_;    }  private:    socket_type socket_;    bool have_remote_endpoint_;    endpoint_type remote_endpoint_;  };  // The implementation type of the socket.  class implementation_type  {  public:    // Default constructor.    implementation_type()      : socket_(invalid_socket),        flags_(0),        cancel_token_(),        protocol_(endpoint_type().protocol()),        next_(0),        prev_(0)    {    }  private:    // Only this service will have access to the internal values.    friend class win_iocp_socket_service;    // The native socket representation.    native_type socket_;    enum    {      enable_connection_aborted = 1, // User wants connection_aborted errors.      close_might_block = 2, // User set linger option for blocking close.      user_set_non_blocking = 4 // The user wants a non-blocking socket.    };    // Flags indicating the current state of the socket.    unsigned char flags_;    // We use a shared pointer as a cancellation token here to work around the    // broken Windows support for cancellation. MSDN says that when you call    // closesocket any outstanding WSARecv or WSASend operations will complete    // with the error ERROR_OPERATION_ABORTED. In practice they complete with    // ERROR_NETNAME_DELETED, which means you can't tell the difference between    // a local cancellation and the socket being hard-closed by the peer.    shared_cancel_token_type cancel_token_;    // The protocol associated with the socket.    protocol_type protocol_;    // The ID of the thread from which it is safe to cancel asynchronous    // operations. 0 means no asynchronous operations have been started yet.    // ~0 means asynchronous operations have been started from more than one    // thread, and cancellation is not supported for the socket.    DWORD safe_cancellation_thread_id_;    // Pointers to adjacent socket implementations in linked list.    implementation_type* next_;    implementation_type* prev_;  };  // The type of the reactor used for connect operations.  typedef detail::select_reactor<true> reactor_type;  // The maximum number of buffers to support in a single operation.  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };  // Constructor.  win_iocp_socket_service(asio::io_service& io_service)    : asio::detail::service_base<        win_iocp_socket_service<Protocol> >(io_service),      iocp_service_(asio::use_service<win_iocp_io_service>(io_service)),      reactor_(0),      mutex_(),      impl_list_(0)  {  }  // Destroy all user-defined handler objects owned by the service.  void shutdown_service()  {    // Close all implementations, causing all operations to complete.    asio::detail::mutex::scoped_lock lock(mutex_);    implementation_type* impl = impl_list_;    while (impl)    {      asio::error_code ignored_ec;      close_for_destruction(*impl);      impl = impl->next_;    }  }  // Construct a new socket implementation.  void construct(implementation_type& impl)  {    impl.socket_ = invalid_socket;    impl.flags_ = 0;    impl.cancel_token_.reset();    impl.safe_cancellation_thread_id_ = 0;    // Insert implementation into linked list of all implementations.    asio::detail::mutex::scoped_lock lock(mutex_);    impl.next_ = impl_list_;    impl.prev_ = 0;    if (impl_list_)      impl_list_->prev_ = &impl;    impl_list_ = &impl;  }  // Destroy a socket implementation.  void destroy(implementation_type& impl)  {    close_for_destruction(impl);    // Remove implementation from linked list of all implementations.    asio::detail::mutex::scoped_lock lock(mutex_);    if (impl_list_ == &impl)      impl_list_ = impl.next_;    if (impl.prev_)      impl.prev_->next_ = impl.next_;    if (impl.next_)      impl.next_->prev_= impl.prev_;    impl.next_ = 0;    impl.prev_ = 0;  }  // Open a new socket implementation.  asio::error_code open(implementation_type& impl,      const protocol_type& protocol, asio::error_code& ec)  {    if (is_open(impl))    {      ec = asio::error::already_open;      return ec;    }    socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(),          protocol.protocol(), ec));    if (sock.get() == invalid_socket)      return ec;    HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock.get());    iocp_service_.register_handle(sock_as_handle);    impl.socket_ = sock.release();    impl.flags_ = 0;    impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter());    impl.protocol_ = protocol;    ec = asio::error_code();    return ec;  }  // Assign a native socket to a socket implementation.  asio::error_code assign(implementation_type& impl,      const protocol_type& protocol, const native_type& native_socket,      asio::error_code& ec)  {    if (is_open(impl))    {      ec = asio::error::already_open;      return ec;    }    iocp_service_.register_handle(native_socket.as_handle());    impl.socket_ = native_socket;    impl.flags_ = 0;    impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter());    impl.protocol_ = protocol;    ec = asio::error_code();    return ec;  }  // Determine whether the socket is open.  bool is_open(const implementation_type& impl) const  {    return impl.socket_ != invalid_socket;  }  // Destroy a socket implementation.  asio::error_code close(implementation_type& impl,      asio::error_code& ec)  {    if (is_open(impl))    {      // Check if the reactor was created, in which case we need to close the      // socket on the reactor as well to cancel any operations that might be      // running there.      reactor_type* reactor = static_cast<reactor_type*>(            interlocked_compare_exchange_pointer(              reinterpret_cast<void**>(&reactor_), 0, 0));      if (reactor)        reactor->close_descriptor(impl.socket_);      if (socket_ops::close(impl.socket_, ec) == socket_error_retval)        return ec;      impl.socket_ = invalid_socket;      impl.flags_ = 0;      impl.cancel_token_.reset();      impl.safe_cancellation_thread_id_ = 0;    }    ec = asio::error_code();    return ec;  }  // Get the native socket representation.  native_type native(implementation_type& impl)  {    return impl.socket_;  }  // Cancel all operations associated with the socket.  asio::error_code cancel(implementation_type& impl,      asio::error_code& ec)  {    if (!is_open(impl))    {      ec = asio::error::bad_descriptor;    }    else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(          ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))    {      // The version of Windows supports cancellation from any thread.      typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);      cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;      socket_type sock = impl.socket_;      HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);      if (!cancel_io_ex(sock_as_handle, 0))      {        DWORD last_error = ::GetLastError();        ec = asio::error_code(last_error,            asio::error::get_system_category());      }      else      {        ec = asio::error_code();      }    }    else if (impl.safe_cancellation_thread_id_ == 0)    {      // No operations have been started, so there's nothing to cancel.      ec = asio::error_code();    }    else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId())    {      // Asynchronous operations have been started from the current thread only,      // so it is safe to try to cancel them using CancelIo.      socket_type sock = impl.socket_;      HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);      if (!::CancelIo(sock_as_handle))      {        DWORD last_error = ::GetLastError();        ec = asio::error_code(last_error,            asio::error::get_system_category());      }      else      {        ec = asio::error_code();      }    }    else    {      // Asynchronous operations have been started from more than one thread,      // so cancellation is not safe.      ec = asio::error::operation_not_supported;    }    return ec;  }  // Determine whether the socket is at the out-of-band data mark.  bool at_mark(const implementation_type& impl,      asio::error_code& ec) const  {    if (!is_open(impl))    {      ec = asio::error::bad_descriptor;      return false;    }    asio::detail::ioctl_arg_type value = 0;    socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec);    return ec ? false : value != 0;  }  // Determine the number of bytes available for reading.  std::size_t available(const implementation_type& impl,      asio::error_code& ec) const  {    if (!is_open(impl))    {      ec = asio::error::bad_descriptor;      return 0;    }    asio::detail::ioctl_arg_type value = 0;    socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec);    return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -