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

Attempting to delete a nested watched folder causes subsequent operation on QFileSystemWatcher to hang

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P1: Critical
    • None
    • 5.4.1
    • None
    • Windows 7, Visual Studio 2012

    Description

      QFileSystemWatcher causes a deadlock in removePath() after an attempt to remove a watched folder using Windows Explorer. To repro, extract the attached zip to C:. Alternatively, create a directory in C: with the following structure and files:

      C:/A
      C:/A/B
      C:/A/B/C
      C:/A/B/C/D
      C:/A/B/C/D/E
      C:/A/B/C/D/F
      C:/A/B/C/D/New Text Document.txt (zero byte file)
      C:/A/B/C/D/E/New Text Document.txt (zero byte file)
      C:/A/B/C/D/F/New folder
      C:/A/B/C/D/F/New Text Document.txt (zero byte file)

      QFileSystemWatcher* watcher = new QFileSystemWatcher;
      QDir dirTemp("C:/A");
      QList<QDir> dirList;
      dirList.append(dirTemp);
      while(dirList.count())
      {
          QDir next = dirList.takeFirst();
          watcher->addPath(next.absolutePath());
          qDebug() << QString("Adding %1 to watcher.").arg(next.absolutePath());
          foreach(const QString dirName, next.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name))
              dirList.append(next.absoluteFilePath(dirName));
      }
          
      QThread::sleep(30);
      watcher->removePath("C:/A/B/C");
      

      While the code is sleeping in the QThread::sleep(30) (I used a breakpoint at the line just to be sure), open up Windows Explorer and attempt to delete "C:/A/B/C/D", after the confirmation to move to recycle bin, you should get a permission prompt. Hit Cancel to cancel the delete.

      The QWindowsFileSystemWatcherEngineThread::run() should now be in a state where it spins indefinitely in the do-while loop with the WaitForMultipleObjects at the end returning something between 0-8 (in my case it returned 7).

      After the QThread::sleep(30) expires, we should hit a deadlock in the next line watcher->removePath("C:/A/B/C"). It appears QWindowsFileSystemWatcherEngine::removePaths is trying to acquire the thread->mutex.

      Attachments

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

        Activity

          People

            cnn Qt Core & Network
            thuan_firelight Thuan Seah
            Votes:
            3 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes