From 6533d1a47309956e8acda90eb4c41d245e817c93 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 23 Jul 2020 18:14:48 +0200 Subject: Fix race in QFseventsFileSystemWatcher destructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Pick-to: 5.15 5.12 Change-Id: Ie168bbe91e55c5559632b37bc008e11597e4fdaf Reviewed-by: Thiago Macieira Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qfilesystemwatcher_fsevents.mm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/corelib/io/qfilesystemwatcher_fsevents.mm') diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index e039559ea3..b6d285cec3 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -311,14 +311,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); } -- cgit v1.2.3