QFileSystemWatcher/Windows: Fix crash when no QCoreApplication is present
Rewrite instantiation of QWindowsRemovableDriveListener to check for the presence of the event dispatcher. Task-number: QTBUG-62242 Change-Id: Ibb5726864058593e5341e0d411aaf5432e2f108a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
245d83bb50
commit
e612fe8d47
@ -127,16 +127,10 @@ private:
|
|||||||
quintptr m_lastMessageHash;
|
quintptr m_lastMessageHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline QEventDispatcherWin32 *winEventDispatcher()
|
|
||||||
{
|
|
||||||
return static_cast<QEventDispatcherWin32 *>(QCoreApplication::instance()->eventDispatcher());
|
|
||||||
}
|
|
||||||
|
|
||||||
QWindowsRemovableDriveListener::QWindowsRemovableDriveListener(QObject *parent)
|
QWindowsRemovableDriveListener::QWindowsRemovableDriveListener(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_lastMessageHash(0)
|
, m_lastMessageHash(0)
|
||||||
{
|
{
|
||||||
winEventDispatcher()->installNativeEventFilter(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stopDeviceNotification(QWindowsRemovableDriveListener::RemovableDriveEntry &e)
|
static void stopDeviceNotification(QWindowsRemovableDriveListener::RemovableDriveEntry &e)
|
||||||
@ -314,7 +308,8 @@ void QWindowsRemovableDriveListener::addPath(const QString &p)
|
|||||||
notify.dbch_size = sizeof(notify);
|
notify.dbch_size = sizeof(notify);
|
||||||
notify.dbch_devicetype = DBT_DEVTYP_HANDLE;
|
notify.dbch_devicetype = DBT_DEVTYP_HANDLE;
|
||||||
notify.dbch_handle = volumeHandle;
|
notify.dbch_handle = volumeHandle;
|
||||||
re.devNotify = RegisterDeviceNotification(winEventDispatcher()->internalHwnd(),
|
QEventDispatcherWin32 *winEventDispatcher = static_cast<QEventDispatcherWin32 *>(QCoreApplication::eventDispatcher());
|
||||||
|
re.devNotify = RegisterDeviceNotification(winEventDispatcher->internalHwnd(),
|
||||||
¬ify, DEVICE_NOTIFY_WINDOW_HANDLE);
|
¬ify, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||||
// Empirically found: The notifications also work when the handle is immediately
|
// Empirically found: The notifications also work when the handle is immediately
|
||||||
// closed. Do it here to avoid having to close/reopen in lock message handling.
|
// closed. Do it here to avoid having to close/reopen in lock message handling.
|
||||||
@ -339,20 +334,24 @@ QWindowsFileSystemWatcherEngine::Handle::Handle()
|
|||||||
|
|
||||||
QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine(QObject *parent)
|
QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine(QObject *parent)
|
||||||
: QFileSystemWatcherEngine(parent)
|
: QFileSystemWatcherEngine(parent)
|
||||||
#ifndef Q_OS_WINRT
|
|
||||||
, m_driveListener(new QWindowsRemovableDriveListener(this))
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_WINRT
|
#ifndef Q_OS_WINRT
|
||||||
parent->setProperty("_q_driveListener",
|
if (QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher()) {
|
||||||
QVariant::fromValue(static_cast<QObject *>(m_driveListener)));
|
m_driveListener = new QWindowsRemovableDriveListener(this);
|
||||||
QObject::connect(m_driveListener, &QWindowsRemovableDriveListener::driveLockForRemoval,
|
eventDispatcher->installNativeEventFilter(m_driveListener);
|
||||||
this, &QWindowsFileSystemWatcherEngine::driveLockForRemoval);
|
parent->setProperty("_q_driveListener",
|
||||||
QObject::connect(m_driveListener, &QWindowsRemovableDriveListener::driveLockForRemovalFailed,
|
QVariant::fromValue(static_cast<QObject *>(m_driveListener)));
|
||||||
this, &QWindowsFileSystemWatcherEngine::driveLockForRemovalFailed);
|
QObject::connect(m_driveListener, &QWindowsRemovableDriveListener::driveLockForRemoval,
|
||||||
QObject::connect(m_driveListener,
|
this, &QWindowsFileSystemWatcherEngine::driveLockForRemoval);
|
||||||
QOverload<const QString &>::of(&QWindowsRemovableDriveListener::driveRemoved),
|
QObject::connect(m_driveListener, &QWindowsRemovableDriveListener::driveLockForRemovalFailed,
|
||||||
this, &QWindowsFileSystemWatcherEngine::driveRemoved);
|
this, &QWindowsFileSystemWatcherEngine::driveLockForRemovalFailed);
|
||||||
|
QObject::connect(m_driveListener,
|
||||||
|
QOverload<const QString &>::of(&QWindowsRemovableDriveListener::driveRemoved),
|
||||||
|
this, &QWindowsFileSystemWatcherEngine::driveRemoved);
|
||||||
|
} else {
|
||||||
|
qWarning("QFileSystemWatcher: Removable drive notification will not work"
|
||||||
|
" if there is no QCoreApplication instance.");
|
||||||
|
}
|
||||||
#endif // !Q_OS_WINRT
|
#endif // !Q_OS_WINRT
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,9 +517,11 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_WINRT
|
#ifndef Q_OS_WINRT
|
||||||
for (const QString &path : paths) {
|
if (Q_LIKELY(m_driveListener)) {
|
||||||
if (!p.contains(path))
|
for (const QString &path : paths) {
|
||||||
m_driveListener->addPath(path);
|
if (!p.contains(path))
|
||||||
|
m_driveListener->addPath(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !Q_OS_WINRT
|
#endif // !Q_OS_WINRT
|
||||||
return p;
|
return p;
|
||||||
|
@ -129,7 +129,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
QList<QWindowsFileSystemWatcherEngineThread *> threads;
|
QList<QWindowsFileSystemWatcherEngineThread *> threads;
|
||||||
#ifndef Q_OS_WINRT
|
#ifndef Q_OS_WINRT
|
||||||
QWindowsRemovableDriveListener *m_driveListener;
|
QWindowsRemovableDriveListener *m_driveListener = nullptr;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user