Sean and I tracked down a nasty race condition today. It turns out that 
ControlObject::addProxy, removeProxy, and updateProxies all touch an 
internal list of ControlObjectThread's (proxies) to update. They all 
touch this list without a lock. addProxy/removeProxy happens whenever a 
ControlObjectThread is created/destroyed. updateProxies happens when 
ControlObject values change and COT's need updating.

If a ControlObjectThread is created or destroyed at the same time that 
updateProxies is running, then it is likely that a nasty segfault will 
occur.

The fix is in the release branch now: 
http://bazaar.launchpad.net/~mixxxdevelopers/mixxx/release-1.6.2/revision/2317

This didn't really show up much before because the standard Mixxx thing 
to do is to create a ControlObjectThread in the constructor of the 
object that will use it, and delete it in the destructor. So generally a 
small number of creations would have to collide with an updateProxies() 
call for that specific control object. This isn't very likely if you 
only do it a couple times per run of Mixxx.

We found this race while tracking down the MidiScriptEngine phantom 
crashes we've been seeing.

As a side note, I found a neat way to reproduce this hard to reproduce 
crash: Replace MidiObject::run() with a while loop that repeatedly sends 
the MIDI sequence required to reproduce the crash. This made the crash 
appear in ~10 seconds each time.

It turns out that this race was responsible for the crashes we were 
seeing in the MidiScriptEngine. I can leave the MIDI spam loop on for 
30+ minutes with no crash.

Cheers,
RJ Ryan

------------------------------------------------------------------------------
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to