From e570a44b372cf56526c128eab646615fa59520fc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 2 Feb 2007 22:46:48 +0000 Subject: [PATCH] don't wake up on Windows messages when waiting for thread termination in a console application as this results in an infinite loop because we never process them and thus they remain in the queue for always (modified patch 1615875; closes bugs 877128) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44344 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 3 +++ include/wx/msw/apptbase.h | 3 +++ include/wx/msw/apptrait.h | 2 ++ src/msw/app.cpp | 13 +++++++++++++ src/msw/basemsw.cpp | 5 +++++ src/msw/thread.cpp | 22 ++++++++++------------ 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index e472d53b51..40eb25ebad 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -29,6 +29,9 @@ wxGTK: - Implemented support for underlined fonts in wxStaticText +wxMSW: + +- Fixed infinite loop in wxThread::Wait() in console applications 2.8.2 diff --git a/include/wx/msw/apptbase.h b/include/wx/msw/apptbase.h index d9c7e9d8ea..f08f50d148 100644 --- a/include/wx/msw/apptbase.h +++ b/include/wx/msw/apptbase.h @@ -40,6 +40,9 @@ public: // process a message while waiting for a(nother) thread, should return // false if and only if we have to exit the application virtual bool DoMessageFromThreadWait() = 0; + + // wait for the handle to be signaled + virtual WXDWORD WaitForThread(WXHANDLE hThread) = 0; }; #endif // _WX_MSW_APPTBASE_H_ diff --git a/include/wx/msw/apptrait.h b/include/wx/msw/apptrait.h index 5d3e733ef3..7b7971a578 100644 --- a/include/wx/msw/apptrait.h +++ b/include/wx/msw/apptrait.h @@ -24,6 +24,7 @@ public: virtual void AfterChildWaitLoop(void *data); virtual bool DoMessageFromThreadWait(); + virtual WXDWORD WaitForThread(WXHANDLE hThread); }; #if wxUSE_GUI @@ -37,6 +38,7 @@ public: virtual bool DoMessageFromThreadWait(); virtual wxPortId GetToolkitVersion(int *majVer, int *minVer) const; + virtual WXDWORD WaitForThread(WXHANDLE hThread); }; #endif // wxUSE_GUI diff --git a/src/msw/app.cpp b/src/msw/app.cpp index d6fc28e390..1554e8637e 100644 --- a/src/msw/app.cpp +++ b/src/msw/app.cpp @@ -225,6 +225,19 @@ bool wxGUIAppTraits::DoMessageFromThreadWait() return evtLoop->Dispatch(); } +DWORD wxGUIAppTraits::WaitForThread(WXHANDLE hThread) +{ + return ::MsgWaitForMultipleObjects + ( + 1, // number of objects to wait for + (HANDLE *)&hThread, // the objects + false, // wait for any objects, not all + INFINITE, // no timeout + QS_ALLINPUT | // return as soon as there are any events + QS_ALLPOSTMESSAGE + ); +} + wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const { OSVERSIONINFO info; diff --git a/src/msw/basemsw.cpp b/src/msw/basemsw.cpp index 033d3a76b2..8ec6130a51 100644 --- a/src/msw/basemsw.cpp +++ b/src/msw/basemsw.cpp @@ -71,3 +71,8 @@ bool wxConsoleAppTraits::DoMessageFromThreadWait() return true; } +WXDWORD wxConsoleAppTraits::WaitForThread(WXHANDLE hThread) +{ + return ::WaitForSingleObject((HANDLE)hThread, INFINITE); +} + diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index ee7fec670d..1aebef4756 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -755,15 +755,16 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs, #if !defined(QS_ALLPOSTMESSAGE) #define QS_ALLPOSTMESSAGE 0 #endif - - result = ::MsgWaitForMultipleObjects - ( - 1, // number of objects to wait for - &m_hThread, // the objects - false, // don't wait for all objects - INFINITE, // no timeout - QS_ALLINPUT|QS_ALLPOSTMESSAGE // return as soon as there are any events - ); + wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL; + if ( traits ) + { + result = traits->WaitForThread(m_hThread); + } + else // can't wait for the thread + { + // so kill it below + result = 0xFFFFFFFF; + } switch ( result ) { @@ -788,9 +789,6 @@ wxThreadInternal::WaitForTerminate(wxCriticalSection& cs, // the system might dead lock then if ( wxThread::IsMain() ) { - wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() - : NULL; - if ( traits && !traits->DoMessageFromThreadWait() ) { // WM_QUIT received: kill the thread -- 2.45.2