예제 #1
0
 void run()
 {
     auto f (bind_handler (
         std::bind (&foo, std::placeholders::_1),
         42));
     f();
     pass();
 }
예제 #2
0
    static void do_completion_impl(operation* op,
        DWORD last_error, size_t bytes_transferred)
    {
      // Take ownership of the operation object.
      typedef read_operation<MutableBufferSequence, Handler> op_type;
      op_type* handler_op(static_cast<op_type*>(op));
      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);

#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
      // Check whether buffers are still valid.
      typename MutableBufferSequence::const_iterator iter
        = handler_op->buffers_.begin();
      typename MutableBufferSequence::const_iterator end
        = handler_op->buffers_.end();
      while (iter != end)
      {
        boost::asio::mutable_buffer buffer(*iter);
        boost::asio::buffer_cast<char*>(buffer);
        ++iter;
      }
#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)

      // Check for the end-of-file condition.
      boost::system::error_code ec(last_error,
          boost::asio::error::get_system_category());
      if (!ec && bytes_transferred == 0 || last_error == ERROR_HANDLE_EOF)
      {
        ec = boost::asio::error::eof;
      }

      // Make a copy of the handler so that the memory can be deallocated before
      // the upcall is made.
      Handler handler(handler_op->handler_);

      // Free the memory associated with the handler.
      ptr.reset();

      // Call the handler.
      boost_asio_handler_invoke_helpers::invoke(
        bind_handler(handler, ec, bytes_transferred), &handler);
    }
예제 #3
0
  void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
      const MutableBufferSequence& buffers, Handler handler)
  {
    if (!is_open(impl))
    {
      this->get_io_service().post(bind_handler(handler,
            boost::asio::error::bad_descriptor, 0));
      return;
    }

    // Update the ID of the thread from which cancellation is safe.
    if (impl.safe_cancellation_thread_id_ == 0)
      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
      impl.safe_cancellation_thread_id_ = ~DWORD(0);

    // Allocate and construct an operation to wrap the handler.
    typedef read_operation<MutableBufferSequence, 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, iocp_service_, buffers, handler);

    // Find first buffer of non-zero length.
    boost::asio::mutable_buffer buffer;
    typename MutableBufferSequence::const_iterator iter = buffers.begin();
    typename MutableBufferSequence::const_iterator end = buffers.end();
    for (DWORD i = 0; iter != end; ++iter, ++i)
    {
      buffer = boost::asio::mutable_buffer(*iter);
      if (boost::asio::buffer_size(buffer) != 0)
        break;
    }

    // A request to receive 0 bytes on a stream handle is a no-op.
    if (boost::asio::buffer_size(buffer) == 0)
    {
      boost::asio::io_service::work work(this->get_io_service());
      ptr.reset();
      boost::system::error_code error;
      iocp_service_.post(bind_handler(handler, error, 0));
      return;
    }

    // Read some data.
    DWORD bytes_transferred = 0;
    ptr.get()->Offset = offset & 0xFFFFFFFF;
    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
    BOOL ok = ::ReadFile(impl.handle_,
        boost::asio::buffer_cast<LPVOID>(buffer),
        static_cast<DWORD>(boost::asio::buffer_size(buffer)),
        &bytes_transferred, ptr.get());
    DWORD last_error = ::GetLastError();
    if (!ok && last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
    {
      boost::asio::io_service::work work(this->get_io_service());
      ptr.reset();
      boost::system::error_code ec(last_error,
          boost::asio::error::get_system_category());
      iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
    }
    else
    {
      ptr.release();
    }
  }