浅析boost asio中的event loop (5)

到了这里,我们已经分析了event loop的基本流程了,接下来就要从使用者的角度来分析一下,event loop一般会管理两类时间,一类是fd的读写,还有一类是timer到期,这里先讨论fd的读写


boost asio中将fd抽象为以下几类service

datagram_socket_service:UDP socket
raw_socket_service:基本的socket
socket_acceptor_service:acceptor socket

stream_socket_service:TCP socket


每类service提供的接口都不同,我们这里只关注实现了TCP的stream_socket_service,它的接口定义可以从boost asio的文档上查到,

这里只是以async_send为例来说明一下基本的流程

stream_socket_service也是一个典型的pImpl模式,它的实现由编译选项决定

#if defined(BOOST_ASIO_HAS_IOCP)
  typedef detail::win_iocp_socket_service service_impl_type;
#else
  typedef detail::reactive_socket_service service_impl_type;
#endif
service_impl_type service_impl_;

对于Linux系统来说,只关注reactive_socket_service,这里的Protocol的要求文档在这里

在reactive_socket_service中对service提供的各种接口提供了实现,以async_send为例

template 
class send_op_base : public reactor_op
{
public:
	send_op_base(socket_type socket, const ConstBufferSequence& buffers,
		socket_base::message_flags flags, func_type complete_func)
	  : reactor_op(&send_op_base::do_perform, complete_func),
		socket_(socket),
		buffers_(buffers),
		flags_(flags)
	{
	}
	
	// 实际执行send操作的地方
	static bool do_perform(reactor_op* base)
	{
	  send_op_base* o(static_cast(base));


	  buffer_sequence_adapter bufs(o->buffers_);


	  for (;;)
	  {
		// Send the data.
		boost::system::error_code ec;
		int bytes = socket_ops::send(o->socket_,
			bufs.buffers(), bufs.count(), o->flags_, ec);


		// Retry operation if interrupted by signal.
		if (ec == boost::asio::error::interrupted)
		  continue;


		// Check if we need to run the operation again.
		if (ec == boost::asio::error::would_block
			|| ec == boost::asio::error::try_again)
		  return false;


		o->ec_ = ec;
		o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
		return true;
	  }
	}


private:
	socket_type socket_;
	ConstBufferSequence buffers_;
	socket_base::message_flags flags_;
};


class send_op : public send_op_base
{
public:
	send_op(socket_type socket, const ConstBufferSequence& buffers,
		socket_base::message_flags flags, Handler handler)
	  : send_op_base(socket,
		  buffers, flags, &send_op::do_complete),
		handler_(handler)
	{
	}
	
	// send完成后调用async_send(const ConstBufferSequence & buffers, WriteHandler handler)中传入的handler回调函数
	// 在这里实现proactor模式
	static void do_complete(io_service_impl* owner, operation* base,
		boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
	{
	  // Take ownership of the handler object.
	  send_op* o(static_cast(base));
	  typedef handler_alloc_traits alloc_traits;
	  handler_ptr ptr(o->handler_, o);


	  // Make the upcall if required.
	  if (owner)
	  {
		// Make a copy of the handler so that the memory can be deallocated
		// before the upcall is made. Even if we're not about to make an
		// upcall, a sub-object of the handler may be the true owner of the
		// memory associated with the handler. Consequently, a local copy of
		// the handler is required to ensure that any owning sub-object remains
		// valid until after we have deallocated the memory here.
		detail::binder2
		  handler(o->handler_, o->ec_, o->bytes_transferred_);
		ptr.reset();
		boost::asio::detail::fenced_block b;
		boost_asio_handler_invoke_helpers::invoke(handler, handler);
	  }
	}


	private:
	Handler handler_;
};


template 
void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
  socket_base::message_flags flags, Handler handler)
{
	// Allocate and construct an operation to wrap the handler.
	// 将send_op封装好
	typedef send_op value_type;
	typedef handler_alloc_traits alloc_traits;
	raw_handler_ptr raw_ptr(handler);
	handler_ptr ptr(raw_ptr,
		impl.socket_, buffers, flags, handler);
	
	// 将send_op放到socket中的write_op对应的queue中
	start_op(impl, reactor::write_op, ptr.get(), true,
		(impl.protocol_.type() == SOCK_STREAM
		  && buffer_sequence_adapter::all_empty(buffers)));
	ptr.release();
}



你可能感兴趣的:(浅析boost asio中的event loop (5))