Show
Ignore:
Timestamp:
05/22/11 05:52:01 (10 years ago)
Author:
jwoithe
Message:

Fix double-free on exit under the new firewire stack. It seems that with the new kernel firewire stack, raw1394_destroy_handle() can take upwards of 20 milliseconds(!) to return. Therefore the IsoHandler?'s disable() call invoked by the IsoTask? (FW_ISORCV or FW_ISOXMT) may not have completed before the "jackd" thread calls ~IsoHandler?(). ~IsoHandler?() thus infers that the handler is still running and calls disable() itself. The practical upshot is that raw1394_destroy_handle() gets called on the same object twice, and a double-free results.

The fix I've implemented is a touch crude, but it appears to work. A mutex is introduced to track the progress of disable(), and this is checked by ~IsoHandler?() before the state of the handler is tested. Any in-progress disable() call is allowed to complete before ~IsoHandler?() tests the state. This prevents the second call of raw1394_destroy_handle() and therefore the double-free cannot occur.

Perhaps as a result of the delays caused by raw1394_destroy_handle(), it seems the handler list can be altered by other threads while updateShadowMapHelper() (called by the IsoTask? threads) is running. A crude test has been added to this function to prevent out-of-range exceptions in most cases.

None of this is particularly elegant but it should work around the double-free issue for the moment. The correct approach is to work out precisely why these concurrency issues are occuring and fix them. However, given that all this will be obsoleted by the in-kernel streaming work at some point in the future, it's arguable that the solution in this patch is sufficient in practice.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved