diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2020-07-23 18:14:48 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2020-07-24 09:47:57 +0000 |
commit | 6533d1a47309956e8acda90eb4c41d245e817c93 (patch) | |
tree | 48fec1aedde822c30b65a172bc854cbdccaf36f5 /src | |
parent | c562c1fc19629fb505acd0f6380604840b634211 (diff) |
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
Pick-to: 5.15 5.12
Change-Id: Ie168bbe91e55c5559632b37bc008e11597e4fdaf
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qfilesystemwatcher_fsevents.mm | 14 |
1 files changed, 8 insertions, 6 deletions
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); } |