[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