Windows file dialog: Clean up thread manually.

Do not use deleteLater() to delete the thread.

Task-number: QTBUG-36357

Change-Id: Ie7c87b92a7c73d5fbac01d4951d387ee2facd05c
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
bb10
Friedemann Kleint 2014-02-04 09:11:01 +01:00 committed by The Qt Project
parent 59892468c9
commit 29804462f4
2 changed files with 29 additions and 4 deletions

View File

@ -502,10 +502,30 @@ template <class BaseClass>
QWindowsDialogHelperBase<BaseClass>::QWindowsDialogHelperBase() :
m_nativeDialog(0),
m_ownerWindow(0),
m_timerId(0)
m_timerId(0),
m_thread(0)
{
}
template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::cleanupThread()
{
if (m_thread) { // Thread may be running if the dialog failed to close.
if (m_thread->isRunning())
m_thread->wait(500);
if (m_thread->isRunning()) {
m_thread->terminate();
m_thread->wait(300);
if (m_thread->isRunning())
qCCritical(lcQpaDialogs) <<__FUNCTION__ << "Failed to terminate thread.";
else
qCWarning(lcQpaDialogs) << __FUNCTION__ << "Thread terminated.";
}
delete m_thread;
m_thread = 0;
}
}
template <class BaseClass>
QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::nativeDialog() const
{
@ -559,7 +579,6 @@ void QWindowsDialogThread::run()
{
qCDebug(lcQpaDialogs) << '>' << __FUNCTION__;
m_dialog->exec(m_owner);
deleteLater();
qCDebug(lcQpaDialogs) << '<' << __FUNCTION__;
}
@ -587,6 +606,7 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
// a subsequent call to exec() may follow. So, start an idle timer
// which will start the dialog thread. If exec() is then called, the
// timer is stopped and dialog->exec() is called directly.
cleanupThread();
if (modal) {
m_timerId = this->startTimer(0);
} else {
@ -599,8 +619,9 @@ template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::startDialogThread()
{
Q_ASSERT(!m_nativeDialog.isNull());
QWindowsDialogThread *thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow);
thread->start();
Q_ASSERT(!m_thread);
m_thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow);
m_thread->start();
stopTimer();
}

View File

@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
class QFileDialog;
class QDialog;
class QThread;
class QWindowsNativeDialogBase;
namespace QWindowsDialogs
@ -68,6 +69,7 @@ class QWindowsDialogHelperBase : public BaseClass
Q_DISABLE_COPY(QWindowsDialogHelperBase)
public:
typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr;
~QWindowsDialogHelperBase() { cleanupThread(); }
virtual void exec();
virtual bool show(Qt::WindowFlags windowFlags,
@ -88,10 +90,12 @@ private:
inline QWindowsNativeDialogBase *ensureNativeDialog();
inline void startDialogThread();
inline void stopTimer();
void cleanupThread();
QWindowsNativeDialogBasePtr m_nativeDialog;
HWND m_ownerWindow;
int m_timerId;
QThread *m_thread;
};
QT_END_NAMESPACE