[glib/wip/subprocess-2013: 6/6] Revert "gmain: Add private API to create Unix child watch that uses waitid()"



commit 4dd79e266b4e4b5110bced71ab51ca2afc709a81
Author: Ryan Lortie <desrt desrt ca>
Date:   Sun Jan 20 16:34:19 2013 -0500

    Revert "gmain: Add private API to create Unix child watch that uses waitid()"
    
    This reverts commit 47d82f236dce51d967228e75361d5c530d104eef.

 configure.ac        |    2 +-
 glib/glib-private.c |    3 +-
 glib/glib-private.h |   10 ---
 glib/gmain.c        |  163 +++++++++++++-------------------------------------
 4 files changed, 45 insertions(+), 133 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 445b1b8..aea8ba5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -992,7 +992,7 @@ AC_MSG_RESULT(unsigned $glib_size_type)
 
 # Check for some functions
 AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem)
-AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid waitid)
+AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid)
 AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat)
 # Check for high-resolution sleep functions
 AC_CHECK_FUNCS(splice)
diff --git a/glib/glib-private.c b/glib/glib-private.c
index 6c2642d..d2da2cd 100644
--- a/glib/glib-private.c
+++ b/glib/glib-private.c
@@ -43,8 +43,7 @@ glib__private__ (void)
     g_get_worker_context,
 
     g_check_setuid,
-    g_main_context_new_with_next_id,
-    g_child_watch_source_new_with_flags
+    g_main_context_new_with_next_id
   };
 
   return &table;
diff --git a/glib/glib-private.h b/glib/glib-private.h
index 8ecfce8..7e2e61e 100644
--- a/glib/glib-private.h
+++ b/glib/glib-private.h
@@ -23,11 +23,6 @@
 #include <glib.h>
 #include "gwakeup.h"
 
-typedef enum {
-  _G_CHILD_WATCH_FLAGS_NONE = 0,
-  _G_CHILD_WATCH_FLAGS_WNOWAIT = (1 << 0)
-} _GChildWatchFlags;
-
 GMainContext *          g_get_worker_context            (void);
 gboolean                g_check_setuid                  (void);
 GMainContext *          g_main_context_new_with_next_id (guint next_id);
@@ -38,9 +33,6 @@ GLIB_AVAILABLE_IN_ALL
 gchar *_glib_get_locale_dir    (void);
 #endif
 
-GSource *               g_child_watch_source_new_with_flags (GPid pid,
-                                                             gint flags);
-
 #define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
 
 typedef struct {
@@ -57,8 +49,6 @@ typedef struct {
 
   gboolean              (* g_check_setuid)              (void);
   GMainContext *        (* g_main_context_new_with_next_id) (guint next_id);
-  GSource *             (* g_child_watch_source_new_with_flags) (GPid pid,
-                                                                 gint flags);
   /* Add other private functions here, initialize them in glib-private.c */
 } GLibPrivateVTable;
 
diff --git a/glib/gmain.c b/glib/gmain.c
index 57dc846..9f9eccc 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -293,9 +293,7 @@ struct _GChildWatchSource
 #ifdef G_OS_WIN32
   GPollFD     poll;
 #else /* G_OS_WIN32 */
-  guint       child_exited : 1;
-  guint       wnowait : 1;
-  guint       reserved : 30;
+  gboolean    child_exited;
 #endif /* G_OS_WIN32 */
 };
 
@@ -4775,82 +4773,6 @@ wake_source (GSource *source)
   G_UNLOCK(main_context_list);
 }
 
-/* This is a hack; we want to use the newer waitid() call, but the use
- * of the waitpid() status code API is baked into the GChildWatchSource
- * callback signature, so we need to synthesize it from the siginfo_t
- * we get from waitid().
- */ 
-#ifdef HAVE_WAITID
-#define __G_MAKE_EXITSTATUS(ecode, signum) ((ecode) << 8 | (signum))
-static gint
-waitpid_status_from_siginfo (siginfo_t *siginfo)
-{
-  G_STATIC_ASSERT(((WIFEXITED (__G_MAKE_EXITSTATUS (1, 0))) &&		\
-		   !(WIFSIGNALED (__G_MAKE_EXITSTATUS (1, 0))) &&	\
-		   (WEXITSTATUS (__G_MAKE_EXITSTATUS (1, 0)) == 1)));
-  G_STATIC_ASSERT((!WIFEXITED (__G_MAKE_EXITSTATUS (0, 1))) &&		\
-		  (WIFSIGNALED (__G_MAKE_EXITSTATUS (0, 1))) &&		\
-		  (WTERMSIG (__G_MAKE_EXITSTATUS (0, 1)) == 1));
-  if (siginfo->si_code == CLD_EXITED)
-    return __G_MAKE_EXITSTATUS(siginfo->si_status, 0);
- else if (siginfo->si_code == CLD_KILLED || siginfo->si_code == CLD_DUMPED)
-   return __G_MAKE_EXITSTATUS(0, siginfo->si_status);
- else
-   return __G_MAKE_EXITSTATUS(0xFF, 0);
-}
-#undef __G_MAKE_EXITSTATUS
-#endif /* HAVE_WAITID */
-
-/* Returns TRUE if we need to wake the source */
-static gboolean
-unix_child_watch_source_waitpid (GChildWatchSource    *source)
-{
-  pid_t pid;
-
-  if (source->child_exited)
-    return FALSE;
-
-#ifdef HAVE_WAITID
-  if (source->wnowait)
-    {
-      siginfo_t siginfo;
-      int r;
-
-      siginfo.si_pid = 0;
-      do
-        r = waitid (P_PID, (id_t)source->pid, &siginfo, WEXITED | WNOHANG | WNOWAIT);
-      while (r == -1 && errno == EINTR);
-
-      if (r == 0 && siginfo.si_pid == source->pid)
-	{
-	  source->child_exited = TRUE;
-	  source->child_status = waitpid_status_from_siginfo (&siginfo);
-	  return TRUE;
-	}
-    } else
-#endif
-    {
-      do
-        pid = waitpid (source->pid, &source->child_status, WNOHANG);
-      while (pid == -1 && errno == EINTR);
-
-      if (pid > 0)
-        {
-          source->child_exited = TRUE;
-          return TRUE;
-        }
-      else if (pid == -1 && errno == ECHILD)
-        {
-          g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_child_watch_add()/g_spawn_sync() either directly or indirectly.");
-          source->child_exited = TRUE;
-          source->child_status = 0;
-          return TRUE;
-        }
-    }
-
-  return FALSE;
-}
-
 static void
 dispatch_unix_signals (void)
 {
@@ -4877,9 +4799,28 @@ dispatch_unix_signals (void)
       for (node = unix_child_watches; node; node = node->next)
         {
           GChildWatchSource *source = node->data;
-	  
-	  if (unix_child_watch_source_waitpid (source))
-	    wake_source ((GSource *) source);
+
+          if (!source->child_exited)
+            {
+              pid_t pid;
+              do
+                {
+                  pid = waitpid (source->pid, &source->child_status, WNOHANG);
+                  if (pid > 0)
+                    {
+                      source->child_exited = TRUE;
+                      wake_source ((GSource *) source);
+                    }
+                  else if (pid == -1 && errno == ECHILD)
+                    {
+                      g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_child_watch_add()/g_spawn_sync() either directly or indirectly.");
+                      source->child_exited = TRUE;
+                      source->child_status = 0;
+                      wake_source ((GSource *) source);
+                    }
+                }
+              while (pid == -1 && errno == EINTR);
+            }
         }
     }
 
@@ -5071,43 +5012,6 @@ g_unix_signal_handler (int signum)
 
 #endif /* !G_OS_WIN32 */
 
-GSource *
-g_child_watch_source_new_with_flags (GPid pid,
-				     gint flags)
-{
-  GSource *source;
-  GChildWatchSource *child_watch_source;
-
-#if defined(G_OS_UNIX) && !defined(HAVE_WAITID)
-  if (flags & _G_CHILD_WATCH_FLAGS_WNOWAIT)
-    return NULL;
-#else
-  source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
-  child_watch_source = (GChildWatchSource *)source;
-
-  child_watch_source->pid = pid;
-#if defined(G_OS_UNIX) && defined(HAVE_WAITID)
-  if (flags & _G_CHILD_WATCH_FLAGS_WNOWAIT)
-    child_watch_source->wnowait = TRUE;
-#endif
-
-#ifdef G_OS_WIN32
-  child_watch_source->poll.fd = (gintptr) pid;
-  child_watch_source->poll.events = G_IO_IN;
-
-  g_source_add_poll (source, &child_watch_source->poll);
-#else /* G_OS_WIN32 */
-  G_LOCK (unix_signal_lock);
-  ensure_unix_signal_handler_installed_unlocked (SIGCHLD);
-  unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source);
-  unix_child_watch_source_waitpid (child_watch_source);
-  G_UNLOCK (unix_signal_lock);
-#endif /* G_OS_WIN32 */
-
-  return source;
-#endif
-}
-
 /**
  * g_child_watch_source_new:
  * @pid: process to watch. On POSIX the pid of a child process. On
@@ -5140,7 +5044,26 @@ g_child_watch_source_new_with_flags (GPid pid,
 GSource *
 g_child_watch_source_new (GPid pid)
 {
-  return g_child_watch_source_new_with_flags (pid, 0);
+  GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
+  GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
+
+  child_watch_source->pid = pid;
+
+#ifdef G_OS_WIN32
+  child_watch_source->poll.fd = (gintptr) pid;
+  child_watch_source->poll.events = G_IO_IN;
+
+  g_source_add_poll (source, &child_watch_source->poll);
+#else /* G_OS_WIN32 */
+  G_LOCK (unix_signal_lock);
+  ensure_unix_signal_handler_installed_unlocked (SIGCHLD);
+  unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source);
+  if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0)
+    child_watch_source->child_exited = TRUE;
+  G_UNLOCK (unix_signal_lock);
+#endif /* G_OS_WIN32 */
+
+  return source;
 }
 
 /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]