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/branches/WX_3_0_BRANCH@76199 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -649,6 +649,7 @@ wxMSW:
|
||||
- Fix handling of deleting directories in wxFileSystemWatcher (Eric Raijmakers).
|
||||
- Disable the use of new style wxDirDialog under Vista to work around a bug in
|
||||
its implementation under this system (jtrauntvein).
|
||||
- Fix wxExecute() keeping open too many thread handles for too long (dannchr).
|
||||
|
||||
wxOSX:
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user