This program should execute f() and if it becomes quiescent, but not halted, the program will execute g(). If f() halts then None() will be published immediately without going quiescent. If either f() or g() publishes the whole thing should be killed. This means that if f() publishes without becoming quiescent (for instance f() = signal), then g() should never run.
Actual behavior
g() runs after f() publishes. And just to really rub it in the interpreter deadlocks.
The deadlock is a lock ordering problem. VirtualClock takes its own lock and then calls checkAlive on a handle which can take the lock of a group up the tree. Group kills take the Group lock and then call unsetQuiescent which takes the VirtualClock lock.
This issue appears to exist in both the released version and master.
Test program
-- Run g if f becomes idle/quiescent but not halted. Kill the whole mess when either half publishes.
def ifIdle[A](f :: lambda() :: A, g :: lambda() :: A) :: A =
x <Some(x)< Vclock(IntegerTimeOrder) >> (
(Vawait(0) >> Some(f()) ; None() ) |
Vawait(1) >> Some(g())
)
val c = Channel()
def test() =
ifIdle(lambda() = "Publish from left", lambda() = Println("FAIL: publication idle")) |
stop
def f(n) if (n :> 0) =
test() >x> Println(x) >> stop ; Println("============") >> f(n-1)
f(1000)
Program
Expected behavior
This program should execute f() and if it becomes quiescent, but not halted, the program will execute g(). If f() halts then None() will be published immediately without going quiescent. If either f() or g() publishes the whole thing should be killed. This means that if f() publishes without becoming quiescent (for instance
f() = signal
), then g() should never run.Actual behavior
g() runs after f() publishes. And just to really rub it in the interpreter deadlocks.
The deadlock is a lock ordering problem. VirtualClock takes its own lock and then calls checkAlive on a handle which can take the lock of a group up the tree. Group kills take the Group lock and then call unsetQuiescent which takes the VirtualClock lock.
This issue appears to exist in both the released version and master.
Test program