Problem
When std::async watchdog fires (request timeout), future.wait_for returns timeout, the response is set to E_TIMEOUT, but the async task continues running to completion. If the task holds a mutex or performs a mutating operation, the handler thread returns to the client while work is still in-flight on the background thread.
If the client retries, two operations can run concurrently on the same target.
Proposed Solution
Implement cooperative cancellation via std::stop_token passed to CoreEngine::handle(). The backend would check stop_token.stop_requested() before performing mutating operations.
Interim step: Document the behavior in protocol spec that timeout responses do not guarantee the operation did not execute.
References
- Correctness audit item 7
daemon/src/server.cpp:207-218
daemon/src/tcp_server.cpp:299-309
Problem
When
std::asyncwatchdog fires (request timeout),future.wait_forreturnstimeout, the response is set toE_TIMEOUT, but the async task continues running to completion. If the task holds a mutex or performs a mutating operation, the handler thread returns to the client while work is still in-flight on the background thread.If the client retries, two operations can run concurrently on the same target.
Proposed Solution
Implement cooperative cancellation via
std::stop_tokenpassed toCoreEngine::handle(). The backend would checkstop_token.stop_requested()before performing mutating operations.Interim step: Document the behavior in protocol spec that timeout responses do not guarantee the operation did not execute.
References
daemon/src/server.cpp:207-218daemon/src/tcp_server.cpp:299-309