diff --git a/src/h2load.cc b/src/h2load.cc index 6cbcd164..7478d503 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -104,15 +104,6 @@ Stats::Stats(size_t req_todo) Stream::Stream() : status_success(-1) {} -namespace { -void readcb(struct ev_loop *loop, ev_io *w, int revents) { - auto client = static_cast(w->data); - if (client->do_read() != 0) { - client->fail(); - } -} -} // namespace - namespace { void writecb(struct ev_loop *loop, ev_io *w, int revents) { auto client = static_cast(w->data); @@ -132,6 +123,20 @@ void writecb(struct ev_loop *loop, ev_io *w, int revents) { } } // namespace +namespace { +void readcb(struct ev_loop *loop, ev_io *w, int revents) { + auto client = static_cast(w->data); + if (client->do_read() != 0) { + client->fail(); + return; + } + if (ev_is_active(&client->wev)) { + writecb(loop, &client->wev, revents); + // client->disconnect() and client->fail() may be called + } +} +} // namespace + Client::Client(Worker *worker, size_t req_todo) : worker(worker), ssl(nullptr), next_addr(config.addrs), reqidx(0), state(CLIENT_IDLE), req_todo(req_todo), req_started(0), req_done(0), diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index a70d4669..5cdfd70a 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -82,6 +82,12 @@ void readcb(struct ev_loop *loop, ev_io *w, int revents) { delete handler; return; } + if (ev_is_active(handler->get_wev())) { + if (handler->do_write() != 0) { + delete handler; + return; + } + } } } // namespace @@ -729,4 +735,6 @@ void ClientHandler::signal_write() { conn_.wlimit.startw(); } RateLimit *ClientHandler::get_rlimit() { return &conn_.rlimit; } RateLimit *ClientHandler::get_wlimit() { return &conn_.wlimit; } +ev_io *ClientHandler::get_wev() { return &conn_.wev; } + } // namespace shrpx diff --git a/src/shrpx_client_handler.h b/src/shrpx_client_handler.h index 7a6b8f65..44662c6a 100644 --- a/src/shrpx_client_handler.h +++ b/src/shrpx_client_handler.h @@ -129,6 +129,7 @@ public: RateLimit *get_wlimit(); void signal_write(); + ev_io *get_wev(); private: Connection conn_; diff --git a/src/shrpx_http2_session.cc b/src/shrpx_http2_session.cc index 51e84f33..4e01d3e3 100644 --- a/src/shrpx_http2_session.cc +++ b/src/shrpx_http2_session.cc @@ -95,6 +95,14 @@ void readcb(struct ev_loop *loop, ev_io *w, int revents) { rv = http2session->do_read(); if (rv != 0) { http2session->disconnect(http2session->should_hard_fail()); + return; + } + if (ev_is_active(http2session->get_wev())) { + rv = http2session->do_write(); + if (rv != 0) { + http2session->disconnect(http2session->should_hard_fail()); + return; + } } } } // namespace