Mercurial > public > mercurial-scm > hg
comparison mercurial/util.py @ 8302:d2ad8c066676
util: simplify pipefilter and avoid subprocess race
The subprocess module is not thread safe. Spawning a thread to read
the output leads to exceptions like this when Mercurial exits:
Exception exceptions.TypeError: TypeError("'NoneType' object is not
callable",) in <bound method Popen.__del__ of <subprocess.Popen
object at 0x9ed0dcc>> ignored
The bug is already reported in the Python bug tracker:
http://bugs.python.org/issue1731717
author | Martin Geisler <mg@lazybytes.net> |
---|---|
date | Thu, 07 May 2009 01:33:44 +0200 |
parents | edd676eae7d7 |
children | 4ff63d699256 |
comparison
equal
deleted
inserted
replaced
8301:b0ce2595777b | 8302:d2ad8c066676 |
---|---|
120 setattr(obj, self.name, result) | 120 setattr(obj, self.name, result) |
121 return result | 121 return result |
122 | 122 |
123 def pipefilter(s, cmd): | 123 def pipefilter(s, cmd): |
124 '''filter string S through command CMD, returning its output''' | 124 '''filter string S through command CMD, returning its output''' |
125 (pin, pout) = popen2(cmd, 'b') | 125 p = subprocess.Popen(cmd, shell=True, close_fds=closefds, |
126 def writer(): | 126 stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
127 try: | 127 pout, perr = p.communicate(s) |
128 pin.write(s) | 128 return pout |
129 pin.close() | |
130 except IOError, inst: | |
131 if inst.errno != errno.EPIPE: | |
132 raise | |
133 | |
134 # we should use select instead on UNIX, but this will work on most | |
135 # systems, including Windows | |
136 w = threading.Thread(target=writer) | |
137 w.start() | |
138 f = pout.read() | |
139 pout.close() | |
140 w.join() | |
141 return f | |
142 | 129 |
143 def tempfilter(s, cmd): | 130 def tempfilter(s, cmd): |
144 '''filter string S through a pair of temporary files with CMD. | 131 '''filter string S through a pair of temporary files with CMD. |
145 CMD is used as a template to create the real command to be run, | 132 CMD is used as a template to create the real command to be run, |
146 with the strings INFILE and OUTFILE replaced by the real names of | 133 with the strings INFILE and OUTFILE replaced by the real names of |