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.