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 { ...@@ -13,7 +13,9 @@ enum class rw_state {
/// Reports that the socket is closed or faulty. /// Reports that the socket is closed or faulty.
failure, failure,
/// Reports that an empty buffer is in use and no operation was performed. /// 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 } // namespace caf::io::network
...@@ -136,6 +136,7 @@ private: ...@@ -136,6 +136,7 @@ private:
size_t written_; size_t written_;
byte_buffer wr_buf_; byte_buffer wr_buf_;
byte_buffer wr_offline_buf_; byte_buffer wr_offline_buf_;
bool wr_op_backoff_;
}; };
} // namespace caf::io::network } // namespace caf::io::network
...@@ -21,7 +21,8 @@ stream::stream(default_multiplexer& backend_ref, native_socket sockfd) ...@@ -21,7 +21,8 @@ stream::stream(default_multiplexer& backend_ref, native_socket sockfd)
defaults::middleman::max_consecutive_reads)), defaults::middleman::max_consecutive_reads)),
read_threshold_(1), read_threshold_(1),
collected_(0), collected_(0),
written_(0) { written_(0),
wr_op_backoff_(false) {
configure_read(receive_policy::at_most(1024)); configure_read(receive_policy::at_most(1024));
} }
...@@ -143,6 +144,13 @@ bool stream::handle_read_result(rw_state read_result, size_t rb) { ...@@ -143,6 +144,13 @@ bool stream::handle_read_result(rw_state read_result, size_t rb) {
case rw_state::indeterminate: case rw_state::indeterminate:
return false; return false;
case rw_state::success: 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) if (rb == 0)
return false; return false;
collected_ += rb; collected_ += rb;
...@@ -168,6 +176,13 @@ void stream::handle_write_result(rw_state write_result, size_t wb) { ...@@ -168,6 +176,13 @@ void stream::handle_write_result(rw_state write_result, size_t wb) {
case rw_state::indeterminate: case rw_state::indeterminate:
prepare_next_write(); prepare_next_write();
break; 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: case rw_state::success:
written_ += wb; written_ += wb;
CAF_ASSERT(written_ <= wr_buf_.size()); 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, ...@@ -94,10 +94,7 @@ rw_state session::do_some(int (*f)(SSL*, void*, int), size_t& result, void* buf,
return rw_state::failure; return rw_state::failure;
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
CAF_LOG_DEBUG("SSL_ERROR_WANT_READ reported"); CAF_LOG_DEBUG("SSL_ERROR_WANT_READ reported");
// Report success to poll on this socket. return rw_state::ssl_error_want_read;
if (len == 0 && strcmp(debug_name, "write_some") == 0)
return rw_state::indeterminate;
return rw_state::success;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
CAF_LOG_DEBUG("SSL_ERROR_WANT_WRITE reported"); CAF_LOG_DEBUG("SSL_ERROR_WANT_WRITE reported");
// Report success to poll on this socket. // 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