Commit 7267d945 authored by Wei Xie's avatar Wei Xie

If write op returns ssl_error_want_read, don't write until SSL connection is established.

parent b9f000ae
......@@ -13,7 +13,9 @@ enum class rw_state {
/// Reports that the socket is closed or faulty.
failure,
/// Reports that an empty buffer is in use and no operation was performed.
indeterminate
indeterminate,
/// Reports an ssl error: ssl_error_want_read
ssl_error_want_read
};
} // namespace caf::io::network
......@@ -136,6 +136,7 @@ private:
size_t written_;
byte_buffer wr_buf_;
byte_buffer wr_offline_buf_;
bool wr_op_backoff_;
};
} // namespace caf::io::network
......@@ -21,7 +21,8 @@ stream::stream(default_multiplexer& backend_ref, native_socket sockfd)
defaults::middleman::max_consecutive_reads)),
read_threshold_(1),
collected_(0),
written_(0) {
written_(0),
wr_op_backoff_(false) {
configure_read(receive_policy::at_most(1024));
}
......@@ -143,6 +144,13 @@ bool stream::handle_read_result(rw_state read_result, size_t rb) {
case rw_state::indeterminate:
return false;
case rw_state::success:
// if it is the first rw_state::success after SSL_connect,
// the ssl connection is established. We recover previous pending write OP.
if(wr_op_backoff_) {
backend().add(operation::write, fd(), this);
wr_op_backoff_ = false;
}
case rw_state::ssl_error_want_read:
if (rb == 0)
return false;
collected_ += rb;
......@@ -168,6 +176,13 @@ void stream::handle_write_result(rw_state write_result, size_t wb) {
case rw_state::indeterminate:
prepare_next_write();
break;
case rw_state::ssl_error_want_read:
// if write op returns ssl_error_want_read, don't write until SSL connection is established.
// otherwise, any write OP will get ssl_error_want_read immediately, causing spinning and high CPU usage.
backend().del(operation::write, fd(), this);
wr_op_backoff_ = true;
if(wb == 0)
break;
case rw_state::success:
written_ += wb;
CAF_ASSERT(written_ <= wr_buf_.size());
......
......@@ -94,10 +94,7 @@ rw_state session::do_some(int (*f)(SSL*, void*, int), size_t& result, void* buf,
return rw_state::failure;
case SSL_ERROR_WANT_READ:
CAF_LOG_DEBUG("SSL_ERROR_WANT_READ reported");
// Report success to poll on this socket.
if (len == 0 && strcmp(debug_name, "write_some") == 0)
return rw_state::indeterminate;
return rw_state::success;
return rw_state::ssl_error_want_read;
case SSL_ERROR_WANT_WRITE:
CAF_LOG_DEBUG("SSL_ERROR_WANT_WRITE reported");
// Report success to poll on this socket.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment