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