diff --git a/lib/system/containers.toit b/lib/system/containers.toit index 323de602d..2ad477063 100644 --- a/lib/system/containers.toit +++ b/lib/system/containers.toit @@ -85,9 +85,10 @@ class Container extends ServiceResourceProxy: constructor.internal_ --handle/int --.id --.gid --on-event/Lambda? --on-stopped/Lambda?: on-event_ = on-event on-stopped_ = on-stopped - super _client_ handle + super _client_ handle --install-finalizer=(not (on-stopped or on-event)) close -> none: + catch --trace: throw "close" // Make sure anyone waiting for the result now or in the future // knows that we got closed before getting an exit code. if not result_.has-value: result_.set null diff --git a/lib/system/services.toit b/lib/system/services.toit index d8203e562..a0775e519 100644 --- a/lib/system/services.toit +++ b/lib/system/services.toit @@ -539,8 +539,8 @@ abstract class ServiceResourceProxy: client_/ServiceClient ::= ? _handle_/int? := ? - constructor .client_ ._handle_: - add-finalizer this:: close + constructor .client_ ._handle_ --install-finalizer/bool=true: + if install-finalizer: add-finalizer this:: close if _handle_ & 1 == 1: ServiceResourceProxyManager_.instance.register client_.id _handle_ this diff --git a/tests/containers-test.toit b/tests/containers-test.toit index 508d39244..b7825a653 100644 --- a/tests/containers-test.toit +++ b/tests/containers-test.toit @@ -4,6 +4,7 @@ import monitor import system.containers +import system import expect show * main arguments: @@ -17,6 +18,7 @@ main arguments: test-images test-start test-background-state-changed + test-finalizer test-images: images/List := containers.images @@ -61,6 +63,15 @@ test-start: expect-equals 0 lambda4-value expect-equals 0 sub4.wait +test-finalizer: + // A container should receive the stop notification even if we don't have + // any pointer to the actual container anymore. + latch := monitor.Latch + containers.start containers.current {:} --on-stopped=(:: latch.set true) + // Force a GC. + system.process-stats --gc + with-timeout --ms=5_000: latch.get + test-background-state-changed: channel := monitor.Channel 1 sub := containers.start containers.current { "background-state-test": true }