aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/servers/httpnull.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-21 18:28:11 +0200
committerGitHub Enterprise <[email protected]>2026-04-21 18:28:11 +0200
commit7136132c4c3ae52becab525bc4ce30f3f36126a9 (patch)
treecc6f5079abd0e0178cb7f3ae4a871d14e16a1682 /src/zenhttp/servers/httpnull.cpp
parent5.8.6-pre0 (diff)
downloadarchived-zen-7136132c4c3ae52becab525bc4ce30f3f36126a9.tar.xz
archived-zen-7136132c4c3ae52becab525bc4ce30f3f36126a9.zip
Fix Windows service shutdown signalling (#999)
Stopping the zenserver Windows service (via `sc stop`, `zen service stop`, system shutdown, or any other SCM path) was being ignored. SCM would eventually force-kill the process after its timeout, giving an ungraceful shutdown. ## Root cause PR #751 ("add simple http client tests", c37421a3b) restructured each HTTP server's `OnRun` loop from ```cpp do { m_ShutdownEvent.Wait(WaitTimeout); } while (!IsApplicationExitRequested()); ``` to ```cpp do { ShutdownRequested = m_ShutdownEvent.Wait(WaitTimeout); } while (!ShutdownRequested); ``` That was well-intentioned — tests wanted to start/stop an HTTP server without touching global process state — but the old loop was the only thing that turned `RequestApplicationExit()` into an actual server wake-up. Once it was removed, `RequestApplicationExit(0)` was silently downgraded to "just sets a flag". The `WindowsService::SvcCtrlHandler` stop path was calling exactly that, so SCM stops stopped working. The sponsor-process check path kept working only because it *also* calls `m_Http->RequestExit()` via `ZenServerBase::RequestExit()`. ## Fix - Restore `IsApplicationExitRequested()` as a secondary exit condition in each HTTP server's `OnRun` loop (`httpsys`, `httpasio`, `httpmulti`, `httpnull`, `httpplugin`) alongside the per-server `m_ShutdownEvent` that #751 introduced. Preserves #751's goal — tests can still call `server->RequestExit()` without touching global state — while making `RequestApplicationExit()` wake the server up again, which the rest of the codebase and `SvcCtrlHandler` assume. - Clean up the service control handler in the same pass: also accept `SERVICE_CONTROL_SHUTDOWN`, report `STOP_PENDING` with a 30s `dwWaitHint` (was 0), drop the redundant second `ReportSvcStatus` call, and remove `ghSvcStopEvent` which nothing ever `Wait()`-ed on. - Advertise `SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN` while running; drop controls while stop-pending/stopped. - Make `WindowsService` destructor virtual (latent UB given `Run()` was already virtual).
Diffstat (limited to 'src/zenhttp/servers/httpnull.cpp')
-rw-r--r--src/zenhttp/servers/httpnull.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/zenhttp/servers/httpnull.cpp b/src/zenhttp/servers/httpnull.cpp
index 9bb7ef3bc..d698bcb9d 100644
--- a/src/zenhttp/servers/httpnull.cpp
+++ b/src/zenhttp/servers/httpnull.cpp
@@ -63,7 +63,7 @@ HttpNullServer::OnRun(bool IsInteractiveSession)
}
ShutdownRequested = m_ShutdownEvent.Wait(WaitTimeout);
- } while (!ShutdownRequested);
+ } while (!ShutdownRequested && !IsApplicationExitRequested());
#else
if (IsInteractiveSession)
{
@@ -73,7 +73,7 @@ HttpNullServer::OnRun(bool IsInteractiveSession)
do
{
ShutdownRequested = m_ShutdownEvent.Wait(WaitTimeout);
- } while (!ShutdownRequested);
+ } while (!ShutdownRequested && !IsApplicationExitRequested());
#endif
}