summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2020-07-23 18:14:48 +0200
committerThiago Macieira <thiago.macieira@intel.com>2020-07-24 09:47:57 +0000
commit6533d1a47309956e8acda90eb4c41d245e817c93 (patch)
tree48fec1aedde822c30b65a172bc854cbdccaf36f5 /src
parentc562c1fc19629fb505acd0f6380604840b634211 (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.mm14
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);
}