]> git.saurik.com Git - wxWidgets.git/commitdiff
implemented notifications of the child process termination (patch 1494439)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 May 2006 23:51:23 +0000 (23:51 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 May 2006 23:51:23 +0000 (23:51 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39407 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/x11/private.h
src/x11/evtloop.cpp
src/x11/utils.cpp

index 1e0216dfad2e6664e11cf95b65c182568788a3d0..5cb334e9f06a16df998e38e6309498327122b7f0 100644 (file)
@@ -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:
 
index 5d5814b0d727b8e6f086293ec893a91e6ebd6760..08406a39bff03407360882679643307b9519700c 100644 (file)
@@ -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_
index 8a703868dec835263e87581254fc7041e5df4feb..fa380fcc0d4ff77c3312b790a73c3874553bb05a 100644 (file)
@@ -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,
index ae71bbe8fc797a3c0fed38612cfb1aea96209859..4640a122212e7ce4cc3a8dce3a77ab3265acfbed 100644 (file)
@@ -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;
+    }
 }
 
 // ----------------------------------------------------------------------------