diff --git a/include/http_data.h b/include/http_data.h index 3db000d4..8588dfe5 100644 --- a/include/http_data.h +++ b/include/http_data.h @@ -41,6 +41,8 @@ struct http_res { std::string body; std::atomic final; + std::shared_mutex mres; + std::atomic is_alive; std::atomic generator = nullptr; diff --git a/include/http_server.h b/include/http_server.h index 41554942..64a35627 100644 --- a/include/http_server.h +++ b/include/http_server.h @@ -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; } diff --git a/src/http_server.cpp b/src/http_server.cpp index 518d3175..8ddb7a72 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp @@ -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(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; }