Handle response write race condition with h2o dispose.

This commit is contained in:
Kishore Nallan 2022-02-14 13:38:51 +05:30
parent 805932c7d7
commit 4549e09063
3 changed files with 13 additions and 5 deletions

View File

@ -41,6 +41,8 @@ struct http_res {
std::string body;
std::atomic<bool> final;
std::shared_mutex mres;
std::atomic<bool> is_alive;
std::atomic<void*> generator = nullptr;

View File

@ -109,6 +109,8 @@ public:
const bool destroy_after_use) :
req(h_req), res(h_res), destroy_after_use(destroy_after_use), res_state(h_req->_req) {
std::shared_lock lk(res->mres);
if(!res->is_alive || req->_req == nullptr || res->generator == nullptr) {
return;
}

View File

@ -261,11 +261,15 @@ void HttpServer::on_res_generator_dispose(void *self) {
//LOG(INFO) << "on_res_generator_dispose fires";
h2o_custom_generator_t* custom_generator = *static_cast<h2o_custom_generator_t**>(self);
custom_generator->res()->final = true;
custom_generator->res()->generator = nullptr;
custom_generator->res()->is_alive = false;
custom_generator->req()->notify();
custom_generator->res()->notify();
// locking to ensure dispose does not happen while the h2o req object is being written to
{
std::unique_lock lk(custom_generator->res()->mres);
custom_generator->res()->final = true;
custom_generator->res()->generator = nullptr;
custom_generator->res()->is_alive = false;
custom_generator->req()->notify();
custom_generator->res()->notify();
}
delete custom_generator;
}