1 # vim: set encoding=utf-8 et sw=4 sts=4 :
8 def __init__(self, name, process, args, kw, callback=None, persist=False):
10 self.process = process
13 self.callback = callback
14 self.persist = persist
16 return 'ProcessInfo(name=%s, pid=%s, persist=%s, cb=%s, args=%s)' % (
17 self.name, self.process.pid, self.persist,
18 self.callback.__name__, self.args)
26 def call(self, name, callback, persist, *args, **kw):
27 proc = subprocess.Popen(*args, **kw)
28 procinfo = ProcessInfo(name, proc, args, kw, callback, persist)
29 self.namemap[name] = self.pidmap[proc.pid] = procinfo
31 def sigchild_handler(self, signum):
33 (pid, status) = os.waitpid(-1, os.WNOHANG)
35 if e.errno is e.ECHILD:
39 if pid in self.pidmap:
41 del self.namemap[p.name]
43 if p.callback is not None:
46 self.call(p.name, p.callback, True, *p.args, **p.kw)
48 (pid, status) = os.waitpid(-1, os.WNOHANG)
50 if e.errno == errno.ECHILD:
54 def __getitem__(self, name):
55 if isinstance(name, basestring): # is a name
56 return self.namemap[name]
58 return self.pidmap[name]
60 def __contains__(self, name):
61 if isinstance(name, basestring): # is a name
62 return name in self.namemap
64 return name in self.pidmap
67 if __name__ == '__main__':
74 def sigchild_handler(signum, stacktrace):
77 print 'SIGCHLD', signum
79 def test_notify(proc):
80 print 'test died:', proc, proc.name, proc.process.pid
82 procman = ProcessManager()
84 signal.signal(signal.SIGCHLD, sigchild_handler)
86 procman.call('test', test_notify, True, ('sleep', '5'))
95 if sig == signal.SIGCHLD:
97 procman.sigchild_handler(sig)