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

📄 win_iocp_io_service.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 2 页
字号:
//// win_iocp_io_service.hpp// ~~~~~~~~~~~~~~~~~~~~~~~//// Copyright (c) 2003-2008 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 BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP#define BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)#include <boost/asio/detail/push_options.hpp>#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>#if defined(BOOST_ASIO_HAS_IOCP)#include <boost/asio/detail/push_options.hpp>#include <limits>#include <boost/throw_exception.hpp>#include <boost/system/system_error.hpp>#include <boost/asio/detail/pop_options.hpp>#include <boost/asio/io_service.hpp>#include <boost/asio/detail/call_stack.hpp>#include <boost/asio/detail/handler_alloc_helpers.hpp>#include <boost/asio/detail/handler_invoke_helpers.hpp>#include <boost/asio/detail/service_base.hpp>#include <boost/asio/detail/socket_types.hpp>#include <boost/asio/detail/timer_queue.hpp>#include <boost/asio/detail/mutex.hpp>namespace boost {namespace asio {namespace detail {class win_iocp_io_service  : public boost::asio::detail::service_base<win_iocp_io_service>{public:  // Base class for all operations. A function pointer is used instead of  // virtual functions to avoid the associated overhead.  //  // This class inherits from OVERLAPPED so that we can downcast to get back to  // the operation pointer from the LPOVERLAPPED out parameter of  // GetQueuedCompletionStatus.  class operation    : public OVERLAPPED  {  public:    typedef void (*invoke_func_type)(operation*, DWORD, size_t);    typedef void (*destroy_func_type)(operation*);    operation(win_iocp_io_service& iocp_service,        invoke_func_type invoke_func, destroy_func_type destroy_func)      : outstanding_operations_(&iocp_service.outstanding_operations_),        invoke_func_(invoke_func),        destroy_func_(destroy_func)    {      Internal = 0;      InternalHigh = 0;      Offset = 0;      OffsetHigh = 0;      hEvent = 0;      ::InterlockedIncrement(outstanding_operations_);    }    void do_completion(DWORD last_error, size_t bytes_transferred)    {      invoke_func_(this, last_error, bytes_transferred);    }    void destroy()    {      destroy_func_(this);    }  protected:    // Prevent deletion through this type.    ~operation()    {      ::InterlockedDecrement(outstanding_operations_);    }  private:    long* outstanding_operations_;    invoke_func_type invoke_func_;    destroy_func_type destroy_func_;  };  // Constructor.  win_iocp_io_service(boost::asio::io_service& io_service)    : boost::asio::detail::service_base<win_iocp_io_service>(io_service),      iocp_(),      outstanding_work_(0),      outstanding_operations_(0),      stopped_(0),      shutdown_(0),      timer_thread_(0),      timer_interrupt_issued_(false)  {  }  void init(size_t concurrency_hint)  {    iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,        static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0))));    if (!iocp_.handle)    {      DWORD last_error = ::GetLastError();      boost::system::system_error e(          boost::system::error_code(last_error,            boost::asio::error::get_system_category()),          "iocp");      boost::throw_exception(e);    }  }  // Destroy all user-defined handler objects owned by the service.  void shutdown_service()  {    ::InterlockedExchange(&shutdown_, 1);    while (::InterlockedExchangeAdd(&outstanding_operations_, 0) > 0)    {      DWORD bytes_transferred = 0;#if (WINVER < 0x0500)      DWORD completion_key = 0;#else      DWORD_PTR completion_key = 0;#endif      LPOVERLAPPED overlapped = 0;      ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,          &completion_key, &overlapped, INFINITE);      if (overlapped)        static_cast<operation*>(overlapped)->destroy();    }    for (std::size_t i = 0; i < timer_queues_.size(); ++i)      timer_queues_[i]->destroy_timers();    timer_queues_.clear();  }  // Initialise the task. Nothing to do here.  void init_task()  {  }  // Register a handle with the IO completion port.  boost::system::error_code register_handle(      HANDLE handle, boost::system::error_code& ec)  {    if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0)    {      DWORD last_error = ::GetLastError();      ec = boost::system::error_code(last_error,          boost::asio::error::get_system_category());    }    else    {      ec = boost::system::error_code();    }    return ec;  }  // Run the event loop until stopped or no more work.  size_t run(boost::system::error_code& ec)  {    if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)    {      ec = boost::system::error_code();      return 0;    }    call_stack<win_iocp_io_service>::context ctx(this);    size_t n = 0;    while (do_one(true, ec))      if (n != (std::numeric_limits<size_t>::max)())        ++n;    return n;  }  // Run until stopped or one operation is performed.  size_t run_one(boost::system::error_code& ec)  {    if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)    {      ec = boost::system::error_code();      return 0;    }    call_stack<win_iocp_io_service>::context ctx(this);    return do_one(true, ec);  }  // Poll for operations without blocking.  size_t poll(boost::system::error_code& ec)  {    if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)    {      ec = boost::system::error_code();      return 0;    }    call_stack<win_iocp_io_service>::context ctx(this);    size_t n = 0;    while (do_one(false, ec))      if (n != (std::numeric_limits<size_t>::max)())        ++n;    return n;  }  // Poll for one operation without blocking.  size_t poll_one(boost::system::error_code& ec)  {    if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)    {      ec = boost::system::error_code();      return 0;    }    call_stack<win_iocp_io_service>::context ctx(this);    return do_one(false, ec);  }  // Stop the event processing loop.  void stop()  {    if (::InterlockedExchange(&stopped_, 1) == 0)    {      if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))      {        DWORD last_error = ::GetLastError();        boost::system::system_error e(            boost::system::error_code(last_error,              boost::asio::error::get_system_category()),            "pqcs");        boost::throw_exception(e);      }    }  }  // Reset in preparation for a subsequent run invocation.  void reset()  {    ::InterlockedExchange(&stopped_, 0);  }  // Notify that some work has started.  void work_started()  {    ::InterlockedIncrement(&outstanding_work_);  }  // Notify that some work has finished.  void work_finished()  {    if (::InterlockedDecrement(&outstanding_work_) == 0)      stop();  }  // Request invocation of the given handler.  template <typename Handler>  void dispatch(Handler handler)  {    if (call_stack<win_iocp_io_service>::contains(this))      boost_asio_handler_invoke_helpers::invoke(handler, &handler);    else      post(handler);  }  // Request invocation of the given handler and return immediately.  template <typename Handler>  void post(Handler handler)  {    // If the service has been shut down we silently discard the handler.    if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)      return;    // Allocate and construct an operation to wrap the handler.    typedef handler_operation<Handler> value_type;    typedef handler_alloc_traits<Handler, value_type> alloc_traits;    raw_handler_ptr<alloc_traits> raw_ptr(handler);    handler_ptr<alloc_traits> ptr(raw_ptr, *this, handler);    // Enqueue the operation on the I/O completion port.    if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, ptr.get()))    {      DWORD last_error = ::GetLastError();      boost::system::system_error e(          boost::system::error_code(last_error,            boost::asio::error::get_system_category()),          "pqcs");      boost::throw_exception(e);    }    // Operation has been successfully posted.    ptr.release();  }  // Request invocation of the given OVERLAPPED-derived operation.  void post_completion(operation* op, DWORD op_last_error,      DWORD bytes_transferred)  {    // Enqueue the operation on the I/O completion port.    if (!::PostQueuedCompletionStatus(iocp_.handle,          bytes_transferred, op_last_error, op))    {      DWORD last_error = ::GetLastError();      boost::system::system_error e(          boost::system::error_code(last_error,            boost::asio::error::get_system_category()),          "pqcs");      boost::throw_exception(e);    }  }  // Add a new timer queue to the service.  template <typename Time_Traits>  void add_timer_queue(timer_queue<Time_Traits>& timer_queue)  {    boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);    timer_queues_.push_back(&timer_queue);  }  // Remove a timer queue from the service.  template <typename Time_Traits>  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)  {    boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);    for (std::size_t i = 0; i < timer_queues_.size(); ++i)    {      if (timer_queues_[i] == &timer_queue)      {        timer_queues_.erase(timer_queues_.begin() + i);        return;      }    }  }  // Schedule a timer in the given timer queue to expire at the specified  // absolute time. The handler object will be invoked when the timer expires.  template <typename Time_Traits, typename Handler>  void schedule_timer(timer_queue<Time_Traits>& timer_queue,      const typename Time_Traits::time_type& time, Handler handler, void* token)  {    // If the service has been shut down we silently discard the timer.    if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)      return;    boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);    if (timer_queue.enqueue_timer(time, handler, token))    {      if (!timer_interrupt_issued_)      {        timer_interrupt_issued_ = true;

⌨️ 快捷键说明

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