[Twisted-Python] [PATCH] to make twisted more "child process friendly"

Manuel Estrada Sainz ranty-bulk at ranty.ddts.net
Fri Jun 21 08:18:35 MDT 2002


 Hello,

 Working on apt-proxy v2 I got stuck trying to get the status of a
 subprocess:

 internet/default.py:76
	signal.signal(signal.SIGCHLD, process.reapProcess)
	
	process.reapProcess will be called for every child that exists,
	which makes imposible to anyone to get the status. And actually
	makes useless calling 'reapProcess' from
	Process.maybeCallProcessEnded

 The patch allows objects to be registered to get the termination status
 of certain processes and changes process.Process to use it.

 I know that now the inline documentation gets outdated, I am willing to
 update it if you guys like the patch.
	
 
 Take care
 
 	ranty

-- 
--- Manuel Estrada Sainz <ranty at debian.org>
                         <ranty at bigfoot.com>
			 <ranty at users.sourceforge.net>
------------------------ <manuel.estrada at hispalinux.es> -------------------
God grant us the serenity to accept the things we cannot change, courage to
change the things we can, and wisdom to know the difference.
-------------- next part --------------
Index: process.py
===================================================================
RCS file: /cvs/Twisted/twisted/internet/process.py,v
retrieving revision 1.15
diff -u -r1.15 process.py
--- process.py	20 May 2002 21:09:35 -0000	1.15
+++ process.py	21 Jun 2002 13:58:23 -0000
@@ -39,6 +39,7 @@
 import abstract, main
 from main import CONNECTION_LOST, CONNECTION_DONE
 
+reapProcessHandlers = {}
 def reapProcess(*args):
     """Reap as many processes as possible (without blocking) via waitpid.
 
@@ -52,10 +53,24 @@
     go away w/o blocking.  I don't want to block.)
     """
     try:
-        os.waitpid(0,os.WNOHANG)
+        pid, status = os.waitpid(0,os.WNOHANG)
+        if reapProcessHandlers.has_key(pid):
+            reapProcessHandlers[pid].processEnded(status)
+            del reapProcessHandlers[pid]
     except:
         pass
 
+def registerReapProccessHandler(pid, process):
+    if reapProcessHandlers.has_key(pid):
+	raise RuntimeError
+    reapProcessHandlers[process.pid] = process
+
+def unregisterReapProccessHandler(pid, process):
+    if not (reapProcessHandlers.has_key(pid)
+            and reapProcessHandlers[pid] == process):
+	raise RuntimeError
+    del reapProcessHandlers[pid]
+
 class ProcessWriter(abstract.FileDescriptor, styles.Ephemeral):
     """(Internal) Helper class to write to Process's stdin.
 
@@ -165,8 +180,8 @@
         stdout_read, stdout_write = os.pipe()
         stderr_read, stderr_write = os.pipe()
         stdin_read,  stdin_write  = os.pipe()
-        pid = os.fork()
-        if pid == 0: # pid is 0 in the child process
+        self.pid = os.fork()
+        if self.pid == 0: # pid is 0 in the child process
             # stop debugging, if I am!  I don't care anymore!
             sys.settrace(None)
             # Destroy my stdin / stdout / stderr (in that order)
@@ -201,6 +216,7 @@
                     os.close(fd)
             os._exit(1)
         self.status = -1
+	registerReapProccessHandler(self.pid, self)
         for fd in stdout_write, stderr_write, stdin_read:
             os.close(fd)
         for fd in (stdout_read, stderr_read, stdin_write):
@@ -275,17 +291,23 @@
     lostErrorConnection = 0
     lostOutConnection = 0
     lostInConnection = 0
+    lostProcess = 0
 
     def maybeCallProcessEnded(self):
         if (self.lostErrorConnection and
             self.lostOutConnection and
-            self.lostInConnection):
+            self.lostInConnection and
+            self.lostProcess):
             try:
                 self.proto.processEnded()
             except:
                 log.deferr()
-            reapProcess()
     
+    def processEnded(self, status):
+        self.status = status
+        self.lostProcess = 1
+        self.maybeCallProcessEnded()
+        
     def inConnectionLost(self):
         del self.writer
         self.lostInConnection = 1


More information about the Twisted-Python mailing list