Closed goodsoft closed 9 years ago
Mmkay, seems it's failing some tests.
I'm surprised to hear about deadlock wtih the EventManager, as I have a test (albeit, nondeterministic) that focuses on just that: https://github.com/johncarl81/transfuse/blob/master/transfuse-api/src/test/java/org/androidtransfuse/event/UnregisterConcurrencyTest.java#L189
Here's a distilled test case for deadlock:
eventManager.register(Event.class, new EventObserver<Event>() {
public void trigger(Event event) {
eventManager.register(Event.class, otherEventObserver); // deadlock!
}
});
eventManager.trigger(new Event());
Hmm, this should be protected against by a reentrant lock...
Apparently writeLock()
called by register()
waits for readLock()
set by trigger()
to be released.
Additionally, a writer can acquire the read lock, but not vice-versa
, states ReentrantReadWriteLock
class documentation
We could move triggerQueue()
to below the finally block. The side effect of this would be that you could unregister from an event and still receive events (see https://github.com/johncarl81/transfuse/blob/master/transfuse-api/src/test/java/org/androidtransfuse/event/UnregisterConcurrencyTest.java#L162)
Yeah, I have done exactly that, and that has failed exactly this test. Not sure how to circumvent this problem
Recalling a conversation I had with some of the Otto devs, if it isn't a big deal that we might see events after calling unregister, we can probably get rid of that lock altogether.
@goodsoft: #175
If a new event observer is registered during event execution, a deadlock occurs due to locked
observersLock
.