[PATCH] util: simplify pipefilter and avoid subprocess race
Martin Geisler
mg at lazybytes.net
Wed May 6 17:46:25 CDT 2009
# HG changeset patch
# User Martin Geisler <mg at lazybytes.net>
# Date 1241649734 -7200
# Node ID 398091553e3d99d12d4db87423a3f29c5a61d172
# Parent b0ce2595777bddf8d4a62119e3a2dfb8ca0078b4
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
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -122,23 +122,10 @@
def pipefilter(s, cmd):
'''filter string S through command CMD, returning its output'''
- (pin, pout) = popen2(cmd, 'b')
- def writer():
- try:
- pin.write(s)
- pin.close()
- except IOError, inst:
- if inst.errno != errno.EPIPE:
- raise
-
- # we should use select instead on UNIX, but this will work on most
- # systems, including Windows
- w = threading.Thread(target=writer)
- w.start()
- f = pout.read()
- pout.close()
- w.join()
- return f
+ p = subprocess.Popen(cmd, shell=True, close_fds=closefds,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ pout, perr = p.communicate(s)
+ return pout
def tempfilter(s, cmd):
'''filter string S through a pair of temporary files with CMD.
More information about the Mercurial-devel
mailing list