-
Notifications
You must be signed in to change notification settings - Fork 38.8k
http: fix submission during shutdown race #34577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -211,7 +211,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) | |
| } | ||
| } | ||
| } | ||
| auto hreq{std::make_unique<HTTPRequest>(req, *static_cast<const util::SignalInterrupt*>(arg))}; | ||
| auto hreq{std::make_shared<HTTPRequest>(req, *static_cast<const util::SignalInterrupt*>(arg))}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remark: Was experimenting with having |
||
|
|
||
| // Early address-based allow check | ||
| if (!ClientAllowed(hreq->GetPeer())) { | ||
|
|
@@ -258,7 +258,7 @@ static void http_request_cb(struct evhttp_request* req, void* arg) | |
| return; | ||
| } | ||
|
|
||
| auto item = [req = std::move(hreq), in_path = std::move(path), fn = i->handler]() { | ||
| auto item = [req = hreq, in_path = std::move(path), fn = i->handler]() { | ||
| std::string err_msg; | ||
| try { | ||
| fn(req.get(), in_path); | ||
|
|
@@ -276,7 +276,13 @@ static void http_request_cb(struct evhttp_request* req, void* arg) | |
| req->WriteReply(HTTP_INTERNAL_SERVER_ERROR, err_msg); | ||
| }; | ||
|
|
||
| [[maybe_unused]] auto _{g_threadpool_http.Submit(std::move(item))}; | ||
| if (auto res = g_threadpool_http.Submit(std::move(item)); !res.has_value()) { | ||
furszy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Assume(hreq.use_count() == 1); // ensure request will be deleted | ||
| // Both SubmitError::Inactive and SubmitError::Interrupted mean shutdown | ||
| LogWarning("HTTP request rejected during server shutdown: '%s'", SubmitErrorString(res.error())); | ||
| hreq->WriteReply(HTTP_SERVICE_UNAVAILABLE, "Request rejected during server shutdown"); | ||
| return; | ||
| } | ||
| } else { | ||
| hreq->WriteReply(HTTP_NOT_FOUND); | ||
| } | ||
|
|
||
furszy marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit message suggestion for 5326821:
Given that I think the unclean shutdown is already fixed in the first commit by using
util::Expectedinstead of throwing exceptions, I think this is somewhat more correct for the second:I don't think it's necessary to classify this as a race condition. I guess it depends on how you define it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taken, thanks!
There is a thread (shutdown - main thread) modifying a resource (thread pool) just before another thread (libevent http handler) accesses it. It is pretty much a race condition to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair.