aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/httpsys.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-09-15 09:06:24 +0200
committerGitHub <[email protected]>2023-09-15 09:06:24 +0200
commita70ad011ed4b32c150421a735ed308df2b79bb24 (patch)
tree096f84c1a7aa338c7eaa3f4a1754b3c9dbeafe9e /src/zenhttp/httpsys.cpp
parent0.2.21 (diff)
downloadzen-a70ad011ed4b32c150421a735ed308df2b79bb24.tar.xz
zen-a70ad011ed4b32c150421a735ed308df2b79bb24.zip
bugfix: http.sys async response handling race (#406)
under heavy load, an async response could end up deleting the HTTP transaction object before the issuing call had completed
Diffstat (limited to 'src/zenhttp/httpsys.cpp')
-rw-r--r--src/zenhttp/httpsys.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/zenhttp/httpsys.cpp b/src/zenhttp/httpsys.cpp
index 2f8e0a898..342fdd047 100644
--- a/src/zenhttp/httpsys.cpp
+++ b/src/zenhttp/httpsys.cpp
@@ -242,6 +242,14 @@ public:
HttpSysServerRequest& ServerRequest() { return m_HandlerRequest.value(); }
+ struct CompletionMutexScope
+ {
+ CompletionMutexScope(HttpSysTransaction& Tx) : Lock(Tx.m_CompletionMutex) {}
+ ~CompletionMutexScope() = default;
+
+ RwLock::ExclusiveLockScope Lock;
+ };
+
private:
OVERLAPPED m_HttpOverlapped{};
HttpSysServer& m_HttpServer;
@@ -680,7 +688,12 @@ HttpAsyncWorkRequest::AsyncWorkItem::Execute()
try
{
- HttpSysServerRequest& ThisRequest = Tx.ServerRequest();
+ // We need to hold this lock while we're issuing new requests in order to
+ // prevent race conditions between the thread we are running on and any
+ // IOCP service threads. Otherwise the IOCP completion handler can end
+ // up deleting the transaction object before we are done with it!
+ HttpSysTransaction::CompletionMutexScope _(Tx);
+ HttpSysServerRequest& ThisRequest = Tx.ServerRequest();
ThisRequest.m_NextCompletionHandler = nullptr;