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