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
parent
59892468c9
commit
29804462f4
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue