Behaviours that wait for promises that are unfilled crash the runtime
lukecheeseman opened this issue · comments
If we create a behaviour that requires a promise but we do not fulfill it, as in the example that follows, then we get a runtime error on shutdown.
class Main {
main() {
var p = Promise.create();
var f = (mut-view p).wait_handle();
when(f) {}
}
}
Gives the error:
veronac: ../../../../src/rt/./cpp/../sched/cown.h:1287: void verona::rt::Cown::collect(verona::rt::Alloc *): Assertion `stub->next.load(std::memory_order_relaxed) == nullptr' failed.
So this is detecting a memory leak. As a cown
is being collected with a non-empty message queue. The failure of this assertion is bad.
I think this can occur if
- Ref count of promise reaches zero.
- Leak detector finds the promise is not reachable from live cowns
- Tear down is the promise is waited on, but is unfulfilled at teardown (your case).
The simplist is to raise this as a more sensible error as a memory leak. However, this might not be the behaviour we are looking for.
I think there is some thoughts on how we should memory manage promises here.
- Should a promise fulfill end be a strong or weak reference?
- Should a promise wait end be a strong or weak reference?
- If something is waiting on a promise, and the fulfull end is dropped, then what should we do?
- Cycles versus non-cycles. Only collecting acyclic promise dependencies?
I think you have uncovered an interesting corner, that we need to design a bit more.