From bd00fe32fb099384c5fdd337e3749ae461ae497f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 28 May 2006 23:51:23 +0000 Subject: [PATCH] implemented notifications of the child process termination (patch 1494439) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39407 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/x11/private.h | 4 ++++ src/x11/evtloop.cpp | 3 +++ src/x11/utils.cpp | 46 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 1e0216dfad..5cb334e9f0 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -299,6 +299,7 @@ wxX11: - Invisible text problem fixed. - Bitmap clipping with masks and scaling improved. - Fixed a crash bug in the generic timer. +- Implemented child process termination notifications (David Björkevik) Unix: diff --git a/include/wx/x11/private.h b/include/wx/x11/private.h index 5d5814b0d7..08406a39bf 100644 --- a/include/wx/x11/private.h +++ b/include/wx/x11/private.h @@ -80,5 +80,9 @@ extern Window wxGetWindowParent(Window window); bool wxSetWMDecorations(Window w, long style); bool wxMWMIsRunning(Window w); +// Checks if any of our children are finished. +// implemented in src/x11/utils.cpp +void wxCheckForFinishedChildren(); + #endif // _WX_PRIVATE_H_ diff --git a/src/x11/evtloop.cpp b/src/x11/evtloop.cpp index 8a703868de..fa380fcc0d 100644 --- a/src/x11/evtloop.cpp +++ b/src/x11/evtloop.cpp @@ -430,6 +430,9 @@ bool wxEventLoop::Dispatch() { XEvent event; + // Start off by checking if any of our child processes have finished. + wxCheckForFinishedChildren(); + // TODO allowing for threads, as per e.g. wxMSW // This now waits until either an X event is received, diff --git a/src/x11/utils.cpp b/src/x11/utils.cpp index ae71bbe8fc..4640a12221 100644 --- a/src/x11/utils.cpp +++ b/src/x11/utils.cpp @@ -91,10 +91,52 @@ bool wxCheckForInterrupt(wxWindow *wnd) // wxExecute stuff // ---------------------------------------------------------------------------- +WX_DECLARE_HASH_MAP( int, wxEndProcessData*, wxIntegerHash, wxIntegerEqual, wxProcMap ); + +static wxProcMap *gs_procmap; + int wxAddProcessCallback(wxEndProcessData *proc_data, int fd) { - // TODO - return 0; + if (!gs_procmap) gs_procmap = new wxProcMap(); + (*gs_procmap)[fd] = proc_data; + return 1; +} + +void wxCheckForFinishedChildren() +{ + wxProcMap::iterator it; + if (!gs_procmap) return; + if (gs_procmap->size() == 0) { + // Map empty, delete it. + delete gs_procmap; + gs_procmap = NULL; + } + for (it = gs_procmap->begin();it != gs_procmap->end(); ++it) + { + wxEndProcessData *proc_data = it->second; + int pid = (proc_data->pid > 0) ? proc_data->pid : -(proc_data->pid); + int status = 0; + // has the process really terminated? + int rc = waitpid(pid, &status, WNOHANG); + if (rc == 0) + continue; // no, it didn't exit yet, continue waiting + + // set exit code to -1 if something bad happened + proc_data->exitcode = rc != -1 && WIFEXITED(status) ? + WEXITSTATUS(status) : -1; + + // child exited, end waiting + close(it->first); + + // don't call us again! + gs_procmap->erase(it->first); + + wxHandleProcessTermination(proc_data); + + // Iterator is invalid. Handle any further children in subsequent + // calls. + break; + } } // ---------------------------------------------------------------------------- -- 2.45.2