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]);