fix: a shared resource must be able to release its waiters
SharedResource::acquire() blocks on a condition variable whose predicate only becomes true when release() hands over ownership. No timeout, no stop condition. A node parked there was not observing stop flags, so teardown had no way to reach it: the worker never returned, the pool's join never completed, and shutdown waited on a resource nobody was going to release — which is precisely the situation when the holder is being stopped too. close() wakes every waiter and refuses further acquisitions, and the waiters leave through ResourceClosedError, which is an exception the node error path already handles rather than a new mechanism. StaticNetwork calls it on registered resources at the top of halt() and shutdown(), before stopping any node, since a node stopped while parked cannot respond to being stopped. The handover needed care in two places. A waiter woken by close() has not been given ownership, so it takes no Guard and leaves held_ exactly as it found it; and release() now skips handing over to waiters when closed, because handing ownership to a thread that is on its way out would leave held_ true with nobody holding it. reopen() is there for reuse across runs, which the persistent-pipeline work will want; teardown does not need it. Verified in both directions: without close() the waiter thread never returns and the test's join blocks; with it the waiter leaves through ResourceClosedError while the holder still has the resource. 145/145.
This commit is contained in:
@@ -220,6 +220,11 @@ struct ResourceSnapshot {
|
||||
struct IResourceProbe {
|
||||
virtual ~IResourceProbe() = default;
|
||||
virtual ResourceSnapshot snapshot(const std::string& name) const = 0;
|
||||
|
||||
/// Release every thread waiting for the resource, so teardown is not held
|
||||
/// up by one. A network calls this on the resources registered with it when
|
||||
/// it halts; default no-op for probes with nothing to wake.
|
||||
virtual void close() {}
|
||||
};
|
||||
|
||||
} // namespace kpn
|
||||
|
||||
Reference in New Issue
Block a user