Skip to content

Instantly share code, notes, and snippets.

@ochinchina
Last active August 5, 2016 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ochinchina/bbc57e6441035c6ca7e90ad49efd039d to your computer and use it in GitHub Desktop.
Save ochinchina/bbc57e6441035c6ca7e90ad49efd039d to your computer and use it in GitHub Desktop.
use the boost epoll_reactor directly

###in boost 1.39

struct BoostEpollHandler {
	BoostEpollHandler( const boost::function<bool (boost::system::error_code&, std::size_t&) >& _performHandler,
				const boost::function<void (const boost::system::error_code&, std::size_t ) >& _completeHandler )
	:performHandler( _performHandler ),
	completeHandler( _completeHandler )
	{
	}
	
	bool perform( boost::system::error_code& ec , std::size_t& bytes_transferred ) {
		return performHandler( ec, bytes_transferred );
	}
	
	void complete(const boost::system::error_code& ec, std::size_t bytes_transferred) {
		completeHandler( ec, bytes_transferred );
	}
	
	boost::function<bool (boost::system::error_code&, std::size_t&) > performHandler;
	boost::function<void (const boost::system::error_code&, std::size_t ) > completeHandler;

};

//DON'T call startRead() in the doRead method
bool doRead( int fd, boost::system::error_code& ec, std::size_t& bytes_transferred ) {
  //start read data from fd
  if( failToRead ) {
    ec = boost::asio::error::not_connected;
    bytes_transferred = 0;
  } else {
    ec = boost::system::error_code();
    bytes_transferred = ...
  }
  return true;
  
}

void readComplete( int fd, const boost::system::error_code& ec, std::size_t bytes_transferred ) {
  if( !ec ) {
    startRead( fd );
  }
}

void startRead( int fd ) {
  boost_epoll_reactor::per_descriptor_data per_descriptor_data = {false,false};

  BoostEpollHandler handler( boost::bind( &doRead, fd, _1, _2 ), boost::bind( &readComplete, fd, _1, _2 ) );
  reactor.start_read_op( fd,
          per_descriptor_data,
          handler,
          false );
}

bool doWrite( int fd, std::string data,  boost::system::error_code& ec, std::size_t& bytes_transferred ) {
	//write data to the fd
	//set ec and bytes_transferred according to the writting operation result
	
	//If write is not completed, return false to ask the epoll_reactor to send the rest
	return noError && writeCompleted;
}

void writeComplete( const boost::system::error_code& ec, std::size_t bytes_transferred) {
	//NOTHING TO DO
}

void startWrite( int fd, const std::string& data ) {
  boost_epoll_reactor::per_descriptor_data per_descriptor_data = {false,false};

  BoostEpollHandler handler( boost::bind( &doWrite, fd, data, _1, _2 ), boost::bind( &writeComplete, _1, _2 ) );
  reactor.start_write_op( fd,
          per_descriptor_data,
          handler,
          false );
}

typedef boost::asio::detail::epoll_reactor<true> boost_epoll_reactor;

//create a fd

int fd = ...
boost_epoll_reactor reactor( io_service );

...
startRead( fd );
...
startWrite( fd, data );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment