You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We currently have this pattern in three different places in container.jl (you can find them by searching for _dont_listen):
functionfoo(a::Agent, filter, priority)
ch =Channel(1)
_listen(a, ch, filter, priority)
...take!(ch) # One or more, but we only `take!` here..._dont_listen(a, ch)
close(ch)
end
This pattern can deadlock and should therefore be avoided.
The problem is that _dont_listen() acquires the _processmsg lock before deregistering the channels, but _listener_notify() and _msgloop()put!() into these channels while holding the _processmsg lock.
@debug"Deliver messages in $(a) [qlen=$(length(a._msgqueue))]"
filter!(a._msgqueue) do msg
for (filt, ch, p) ∈ a._listeners
if_matches(filt, msg)
isready(ch) &&returntrue
put!(ch, msg)
returnfalse
end
end
true
end
catch ex
@warn"Message delivery failed: $(ex)"
end
end
end
@debug"Stop $(a) message loop"
end
The deadlock occurs if
there is currently a message waiting in the channel, and
the put!() happens after the last take!() and before the _dont_listen().
A possible solution could be to move the close(ch) before the _dont_listen(a, ch) and make sure that the put!() handle the case of closed channels correctly, but as usual, this should be carefully analysed and discussed first.
The text was updated successfully, but these errors were encountered:
We currently have this pattern in three different places in
container.jl
(you can find them by searching for_dont_listen
):This pattern can deadlock and should therefore be avoided.
The problem is that
_dont_listen()
acquires the_processmsg
lock before deregistering the channels, but_listener_notify()
and_msgloop()
put!()
into these channels while holding the_processmsg
lock.Fjage.jl/src/container.jl
Lines 1196 to 1205 in dc74a5e
Fjage.jl/src/container.jl
Lines 1207 to 1213 in dc74a5e
Fjage.jl/src/container.jl
Lines 1236 to 1258 in dc74a5e
The deadlock occurs if
put!()
happens after the lasttake!()
and before the_dont_listen()
.A possible solution could be to move the
close(ch)
before the_dont_listen(a, ch)
and make sure that theput!()
handle the case of closed channels correctly, but as usual, this should be carefully analysed and discussed first.The text was updated successfully, but these errors were encountered: