From 25df1642194a95d68e95fa4169e0053275260608 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 25 Dec 2016 23:03:57 +0900 Subject: [PATCH] nghttpx: Don't write again after failure Plain write(2) is OK, but SSL_write requires same arguments on retry. It would be better to avoid calling them again. --- src/shrpx_http2_session.cc | 9 +++++++-- src/shrpx_http2_session.h | 3 +++ src/shrpx_http_downstream_connection.cc | 13 +++++++++---- src/shrpx_http_downstream_connection.h | 2 ++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 24d9cbd5..ce427a7f 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -2026,7 +2026,7 @@ int Http2Session::write_clear() { // contain part of response body. So keep reading. Invoke // read event to get read(2) error just in case. ev_feed_event(conn_.loop, &conn_.rev, EV_READ); - wb_.drain(wb_.rleft()); + write_ = &Http2Session::write_void; break; } @@ -2141,7 +2141,7 @@ int Http2Session::write_tls() { // contain part of response body. So keep reading. Invoke // read event to get read(2) error just in case. ev_feed_event(conn_.loop, &conn_.rev, EV_READ); - wb_.drain(wb_.rleft()); + write_ = &Http2Session::write_void; break; } @@ -2165,6 +2165,11 @@ int Http2Session::write_tls() { return 0; } +int Http2Session::write_void() { + conn_.wlimit.stopw(); + return 0; +} + bool Http2Session::should_hard_fail() const { switch (state_) { case PROXY_CONNECTING: diff --git a/src/shrpx_http2_session.h b/src/shrpx_http2_session.h index 3dce8084..bcc4fa45 100644 --- a/src/shrpx_http2_session.h +++ b/src/shrpx_http2_session.h @@ -114,6 +114,9 @@ public: int tls_handshake(); int read_tls(); int write_tls(); + // This is a special write function which just stop write event + // watcher. + int write_void(); int downstream_read_proxy(const uint8_t *data, size_t datalen); int downstream_connect_proxy(); diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index c1615730..28a3b167 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -200,7 +200,8 @@ HttpDownstreamConnection::HttpDownstreamConnection( ioctrl_(&conn_.rlimit), response_htp_{0}, initial_addr_idx_(initial_addr_idx), - reuse_first_write_done_(true) {} + reuse_first_write_done_(true), + reusable_(true) {} HttpDownstreamConnection::~HttpDownstreamConnection() { if (LOG_ENABLED(INFO)) { @@ -1157,7 +1158,8 @@ int HttpDownstreamConnection::write_clear() { // part of response body. So keep reading. Invoke read event // to get read(2) error just in case. ev_feed_event(conn_.loop, &conn_.rev, EV_READ); - input->drain(input->rleft()); + do_write_ = &HttpDownstreamConnection::noop; + reusable_ = false; break; } @@ -1285,7 +1287,8 @@ int HttpDownstreamConnection::write_tls() { // part of response body. So keep reading. Invoke read event // to get read(2) error just in case. ev_feed_event(conn_.loop, &conn_.rev, EV_READ); - input->drain(input->rleft()); + do_write_ = &HttpDownstreamConnection::noop; + reusable_ = false; break; } @@ -1445,7 +1448,9 @@ HttpDownstreamConnection::get_downstream_addr_group() const { DownstreamAddr *HttpDownstreamConnection::get_addr() const { return addr_; } -bool HttpDownstreamConnection::poolable() const { return !group_->retired; } +bool HttpDownstreamConnection::poolable() const { + return !group_->retired && reusable_; +} const Address *HttpDownstreamConnection::get_raddr() const { return raddr_; } diff --git a/src/shrpx_http_downstream_connection.h b/src/shrpx_http_downstream_connection.h index bb3dcefc..ac469bf4 100644 --- a/src/shrpx_http_downstream_connection.h +++ b/src/shrpx_http_downstream_connection.h @@ -112,6 +112,8 @@ private: // true if first write of reused connection succeeded. For // convenience, this is initialized as true. bool reuse_first_write_done_; + // true if this object can be reused + bool reusable_; }; } // namespace shrpx