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.
This commit is contained in:
Tatsuhiro Tsujikawa 2016-12-25 23:03:57 +09:00
parent ba03c082e9
commit 25df164219
4 changed files with 21 additions and 6 deletions

View File

@ -2026,7 +2026,7 @@ int Http2Session::write_clear() {
// contain part of response body. So keep reading. Invoke // contain part of response body. So keep reading. Invoke
// read event to get read(2) error just in case. // read event to get read(2) error just in case.
ev_feed_event(conn_.loop, &conn_.rev, EV_READ); ev_feed_event(conn_.loop, &conn_.rev, EV_READ);
wb_.drain(wb_.rleft()); write_ = &Http2Session::write_void;
break; break;
} }
@ -2141,7 +2141,7 @@ int Http2Session::write_tls() {
// contain part of response body. So keep reading. Invoke // contain part of response body. So keep reading. Invoke
// read event to get read(2) error just in case. // read event to get read(2) error just in case.
ev_feed_event(conn_.loop, &conn_.rev, EV_READ); ev_feed_event(conn_.loop, &conn_.rev, EV_READ);
wb_.drain(wb_.rleft()); write_ = &Http2Session::write_void;
break; break;
} }
@ -2165,6 +2165,11 @@ int Http2Session::write_tls() {
return 0; return 0;
} }
int Http2Session::write_void() {
conn_.wlimit.stopw();
return 0;
}
bool Http2Session::should_hard_fail() const { bool Http2Session::should_hard_fail() const {
switch (state_) { switch (state_) {
case PROXY_CONNECTING: case PROXY_CONNECTING:

View File

@ -114,6 +114,9 @@ public:
int tls_handshake(); int tls_handshake();
int read_tls(); int read_tls();
int write_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_read_proxy(const uint8_t *data, size_t datalen);
int downstream_connect_proxy(); int downstream_connect_proxy();

View File

@ -200,7 +200,8 @@ HttpDownstreamConnection::HttpDownstreamConnection(
ioctrl_(&conn_.rlimit), ioctrl_(&conn_.rlimit),
response_htp_{0}, response_htp_{0},
initial_addr_idx_(initial_addr_idx), initial_addr_idx_(initial_addr_idx),
reuse_first_write_done_(true) {} reuse_first_write_done_(true),
reusable_(true) {}
HttpDownstreamConnection::~HttpDownstreamConnection() { HttpDownstreamConnection::~HttpDownstreamConnection() {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
@ -1157,7 +1158,8 @@ int HttpDownstreamConnection::write_clear() {
// part of response body. So keep reading. Invoke read event // part of response body. So keep reading. Invoke read event
// to get read(2) error just in case. // to get read(2) error just in case.
ev_feed_event(conn_.loop, &conn_.rev, EV_READ); ev_feed_event(conn_.loop, &conn_.rev, EV_READ);
input->drain(input->rleft()); do_write_ = &HttpDownstreamConnection::noop;
reusable_ = false;
break; break;
} }
@ -1285,7 +1287,8 @@ int HttpDownstreamConnection::write_tls() {
// part of response body. So keep reading. Invoke read event // part of response body. So keep reading. Invoke read event
// to get read(2) error just in case. // to get read(2) error just in case.
ev_feed_event(conn_.loop, &conn_.rev, EV_READ); ev_feed_event(conn_.loop, &conn_.rev, EV_READ);
input->drain(input->rleft()); do_write_ = &HttpDownstreamConnection::noop;
reusable_ = false;
break; break;
} }
@ -1445,7 +1448,9 @@ HttpDownstreamConnection::get_downstream_addr_group() const {
DownstreamAddr *HttpDownstreamConnection::get_addr() const { return addr_; } 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_; } const Address *HttpDownstreamConnection::get_raddr() const { return raddr_; }

View File

@ -112,6 +112,8 @@ private:
// true if first write of reused connection succeeded. For // true if first write of reused connection succeeded. For
// convenience, this is initialized as true. // convenience, this is initialized as true.
bool reuse_first_write_done_; bool reuse_first_write_done_;
// true if this object can be reused
bool reusable_;
}; };
} // namespace shrpx } // namespace shrpx