Closed notgull closed 6 months ago
It seems like this can also happen with the needs_notification
optimization under loom's model.
MIRI tests on async-lock
pass with #139, so it looks like this is the underlying issue for https://github.com/smol-rs/event-listener/issues/123
The following logic exists in
notify
:https://github.com/smol-rs/event-listener/blob/fdbe437699680bb5e402bc89aa2a0dd12a1ebc25/src/lib.rs#L440
The intent is to make it so
notify
ing anEvent
that has never has anEventListener
is a single atomic operation and nothing else. However, a race condition can happen here where a notification is dropped even when there is a listener available.listen()
. As part oflisten()
theinner()
function is called, which allocates theArc<Inner>
andcompare_exchanges
it into theinner
pointer.load
of theinner
pointer and the finalcompare_exchange
, Thread 0 is pre-empted and Thread 1 starts.notify
, which then callstry_inner
, whichload
s theinner
pointer. Since it hasn't been updated yet this returns0
, which thenotify
function interprets as the event not listening yet.notify
by notifying no listeners.If Thread 0 pre-empted Thread 1 while Thread 1 was updating some atomic state, this can lead to a deadlock.