6 #include <boost/asio/ip/tcp.hpp>     8 #include "util/asio/yield.h"    17   using error_code = ::boost::system::error_code;
    18   using next_layer_type = ::boost::asio::ip::tcp::socket;
    35   error_code ClientWaitToConnect(uint32_t ms);
    40   template <
typename MBS> 
size_t read_some(
const MBS& bufs, error_code& ec);
    45   template <
typename BS> 
size_t write_some(
const BS& bufs, error_code& ec);
    47   next_layer_type::native_handle_type native_handle() { 
return sock_.native_handle(); }
    49   bool is_open()
 const { 
return is_open_; }
    54   void Shutdown(error_code& ec);
    56   next_layer_type::endpoint_type remote_endpoint(error_code& ec)
 const {
    57     return sock_.remote_endpoint(ec);
    60   error_code status()
 const { 
return status_;}
    63   next_layer_type& next_layer() { 
return sock_; }
    68   bool keep_alive()
 const { 
return keep_alive_;}
    69   void set_keep_alive(
bool flag) { keep_alive_ = flag;}
    74   void InitiateConnection();
    79   error_code Reconnect(
const std::string& hname, 
const std::string& service);
    80   void SetStatus(
const error_code& ec, 
const char* where);
    86   bool is_open_ = 
true, keep_alive_ = 
false;
    87   enum State { READ_IDLE, READ_ACTIVE } read_state_ = READ_IDLE;
    90   next_layer_type sock_;
    91   std::unique_ptr<uint8_t[]> rbuf_;
    92   ::boost::asio::mutable_buffer rslice_;
    94   std::string hname_, port_;
    99   std::unique_ptr<ClientData> clientsock_data_;
   102 template <
typename MBS> 
size_t FiberSocketImpl::read_some(
const MBS& bufs, error_code& ec) {
   103   using namespace boost;
   104   if (rslice_.size()) {
   105     size_t copied = asio::buffer_copy(bufs, rslice_);
   106     if (rslice_.size() == copied) {
   107       rslice_ = asio::mutable_buffer(rbuf_.get(), 0);
   111     if (clientsock_data_) {
   122   size_t user_size = asio::buffer_size(bufs);
   123   auto new_seq = make_buffer_seq(bufs, asio::mutable_buffer(rbuf_.get(), rbuf_size_));
   125   size_t read_size = sock_.read_some(new_seq, ec);
   126   if (ec == asio::error::would_block) {
   127     read_state_ = READ_ACTIVE;
   128     read_size = sock_.async_read_some(new_seq, fibers_ext::yield[ec]);
   129     read_state_ = READ_IDLE;
   132     SetStatus(ec, 
"read_some");
   134   if (clientsock_data_) {
   137   if (read_size > user_size) {
   138     rslice_ = asio::mutable_buffer(rbuf_.get(), read_size - user_size);
   139     read_size = user_size;
   144 template <
typename BS> 
size_t FiberSocketImpl::write_some(
const BS& bufs, error_code& ec) {
   145   size_t res = sock_.write_some(bufs, ec);
   146   if (ec == ::boost::asio::error::would_block) {
   147     return sock_.async_write_some(bufs, fibers_ext::yield[ec]);