Fix race in QFseventsFileSystemWatcher destructor

The race goes like this:
1) We destruct QFseventsFileSystemWatcher, which calls FSEventStreamStop
   and FSEventStreamInvalidate/FSEventStreamRelease
2) The FSEvent* calls will happen on the same thread as the destructor
   is being called on, which will be different to the thread that the
   FSEvent* events are popping out on.
3) So, there could be a case where we are in the middle of processing an
   event, but the QFseventsFileSystemWatcher has already died.

The fix is to dispatch the stop/invalidate/release on the queue
associated with the stream.

Patch by Matt Galloway!

Fixes: QTBUG-85594
Change-Id: Ie168bbe91e55c5559632b37bc008e11597e4fdaf
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 6533d1a47309956e8acda90eb4c41d245e817c93)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Erik Verbruggen 2020-07-23 18:14:48 +02:00 committed by Qt Cherry-pick Bot
parent 47a842ee0c
commit a6699dd0df

View File

@ -310,14 +310,16 @@ QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
{
QMacAutoReleasePool pool;
// Stop the stream in case we have to wait for the lock below to be acquired.
if (stream)
FSEventStreamStop(stream);
dispatch_sync(queue, ^{
// Stop the stream in case we have to wait for the lock below to be acquired.
if (stream)
FSEventStreamStop(stream);
// The assumption with the locking strategy is that this class cannot and will not be subclassed!
QMutexLocker locker(&lock);
// The assumption with the locking strategy is that this class cannot and will not be subclassed!
QMutexLocker locker(&lock);
stopStream(true);
stopStream(true);
});
dispatch_release(queue);
}