Close monitoring thread handles as soon as possible in wxMSW.

Don't leave the handles of all threads used for monitoring the child processes
open until the main process termination, rather close them as soon as the
monitored process terminates.

This ensures that we don't accumulate potentially unbounded number of open
handles if we keep launching new child processes. An even better idea would be
to actually use a single thread for monitoring all of them, but this fix is
much simpler and should fix the most acute problem for now.

Closes #16123.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76200 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-03-27 00:02:16 +00:00
parent 6548217b37
commit d9a5f4a0bb

View File

@@ -121,6 +121,14 @@ static wxVector<HANDLE> gs_asyncThreads;
struct wxExecuteData
{
public:
wxExecuteData()
{
// The rest is initialized in the code creating the objects of this
// class, but the thread handle can't be set until later, so initialize
// it here to ensure we never use an uninitialized value in our dtor.
hThread = 0;
}
~wxExecuteData()
{
if ( !::CloseHandle(hProcess) )
@@ -131,6 +139,7 @@ public:
HWND hWnd; // window to send wxWM_PROC_TERMINATED to
HANDLE hProcess; // handle of the process
HANDLE hThread; // handle of the thread monitoring its termination
DWORD dwProcessId; // pid of the process
wxProcess *handler;
DWORD dwExitCode; // the exit code of the process
@@ -361,6 +370,21 @@ LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
else
{
// asynchronous execution - we should do the clean up
for ( wxVector<HANDLE>::iterator it = gs_asyncThreads.begin();
it != gs_asyncThreads.end();
++it )
{
if ( *it == data->hThread )
{
gs_asyncThreads.erase(it);
if ( !::CloseHandle(data->hThread) )
{
wxLogLastError(wxT("CloseHandle(hThread)"));
}
break;
}
}
delete data;
}
@@ -978,6 +1002,7 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
}
gs_asyncThreads.push_back(hThread);
data->hThread = hThread;
#if wxUSE_IPC && !defined(__WXWINCE__)
// second part of DDE hack: now establish the DDE conversation with the