# HG changeset patch # User Martin Geisler # Date 2009-05-06 23:33:44 # Node ID d2ad8c066676c0dd8fc4a4d77e490899db7f31b4 # 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 > 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 @@ class propertycache(object): 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.