Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-93291

QFileSystemWatcher not safe wrt moveToThread

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P2: Important
    • None
    • 5.15.2
    • Core: I/O
    • None
    • Windows

    Description

      In a complex application I tried to push the QFileSystemWatcher off the main thread, as it does excessive stat syscalls which can lead to the UI being blocked for a long time when calling addPaths.

      To do that, I basically did this:

      auto watcher = new QFileSystemWatcher;
      watcher->moveToThread(someBackgroundThread);
      // connect to signals, etc.
      // then interact with the normal API via thread safe events:
      QMetaObject::invokeMethod(watcher, [watcher, paths]() {
          watcher->addPaths(path);
      });
      
      // once done with the watcher:
      watcher->deleteLater();
      

      This worked fine on macOS and Linux, but on Windows I started to see strange crashes in our unit tests with this backtrace:

      ucrtbase.dll!abort() Unknown
        vcruntime140.dll!_purecall() Line 29 C++
      > Qt5Core.dll!QAbstractEventDispatcher::filterNativeEvent(const QByteArray & eventType, void * message, long * result) Line 495 C++
        Qt5Core.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 605 C++
        Qt5Core.dll!QCoreApplication::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags, int ms) Line 1316 C++
        Qt5Core.dll!QTest::qWait(int ms) Line 105 C++
        tst_dataset.exe!TestDataset::test_duplicateChannelFileExport() Line 121 C++
      

      I believe this comes from the fact that QFileSystemWatcher is not moveToThread safe:

      
      QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine(QObject *parent)
          : QFileSystemWatcherEngine(parent)
      {
      #ifndef Q_OS_WINRT
          if (QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance()) {
              m_driveListener = new QWindowsRemovableDriveListener(this);
              eventDispatcher->installNativeEventFilter(m_driveListener);
      

      this gets called on construction of the QFileSystemWatcher, but there is no handling of a QEvent::ThreadChange in that class, which should remove the event filter and then re-add it in the new thread.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              thiago Thiago Macieira
              milianw Milian Wolff
              Votes:
              1 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes