Mercurial > hg
changeset 18759:9baf4330d88f
sshpeer: store subprocess so it cleans up correctly
When running 'hg pull --rebase', I was seeing this exception 100% of the
time as the python process was closing down:
Exception TypeError: TypeError("'NoneType' object is not callable",) in
<bound method Popen.__del__ of <subprocess.Popen object at 0x937c10>> ignored
By storing the subprocess on the sshpeer, the subprocess seems to clean up
correctly, and I no longer see the exception. I have no idea why this actually
works, but I get a 0% repro if I store the subprocess in self.subprocess,
and a 100% repro if I store None in self.subprocess.
Possibly related to issue 2240.
author | Durham Goode <durham@fb.com> |
---|---|
date | Fri, 08 Mar 2013 16:59:36 -0800 |
parents | 6aca4d1c744e |
children | e74704c33e24 |
files | mercurial/sshpeer.py mercurial/util.py |
diffstat | 2 files changed, 9 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/sshpeer.py Thu Feb 28 10:12:26 2013 -0800 +++ b/mercurial/sshpeer.py Fri Mar 08 16:59:36 2013 -0800 @@ -70,7 +70,10 @@ (_serverquote(remotecmd), _serverquote(self.path)))) ui.note(_('running %s\n') % cmd) cmd = util.quotecommand(cmd) - self.pipeo, self.pipei, self.pipee = util.popen3(cmd) + + # while self.subprocess isn't used, having it allows the subprocess to + # to clean up correctly later + self.pipeo, self.pipei, self.pipee, self.subprocess = util.popen4(cmd) # skip any noise generated by remote shell self._callstream("hello")
--- a/mercurial/util.py Thu Feb 28 10:12:26 2013 -0800 +++ b/mercurial/util.py Fri Mar 08 16:59:36 2013 -0800 @@ -129,13 +129,17 @@ return p.stdin, p.stdout def popen3(cmd, env=None, newlines=False): + stdin, stdout, stderr, p = popen4(cmd, env, newlines) + return stdin, stdout, stderr + +def popen4(cmd, env=None, newlines=False): p = subprocess.Popen(cmd, shell=True, bufsize=-1, close_fds=closefds, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=newlines, env=env) - return p.stdin, p.stdout, p.stderr + return p.stdin, p.stdout, p.stderr, p def version(): """Return version information if available."""