Rev 4825: (andrew) Terminate ssh subprocesses when no references to them in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Nov 25 09:18:20 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4825 [merge]
revision-id: pqm at pqm.ubuntu.com-20091125091819-a6bl1tg0tgs7r6in
parent: pqm at pqm.ubuntu.com-20091125001411-8on8cok7aonp4phz
parent: andrew.bennetts at canonical.com-20091125072743-v6sv4m2mkt9iyslp
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2009-11-25 09:18:19 +0000
message:
  (andrew) Terminate ssh subprocesses when no references to them
  	remain. (#426662)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/transport/ssh.py        ssh.py-20060824042150-0s9787kng6zv1nwq-1
=== modified file 'NEWS'
--- a/NEWS	2009-11-24 08:15:17 +0000
+++ b/NEWS	2009-11-25 07:27:43 +0000
@@ -43,6 +43,9 @@
 * Lots of bugfixes for the test suite on Windows. We should once again
   have a test suite with no failures on Windows. (John Arbash Meinel)
 
+* Terminate ssh subprocesses when no references to them remain, fixing
+  subprocess and file descriptor leaks.  (Andrew Bennetts, #426662)
+  
 * The new glob expansion on Windows would replace all ``\`` characters
   with ``/`` even if it there wasn't a glob to expand, the arg was quoted,
   etc. Now only change slashes if there is something being glob expanded.

=== modified file 'bzrlib/transport/ssh.py'
--- a/bzrlib/transport/ssh.py	2009-11-07 08:02:13 +0000
+++ b/bzrlib/transport/ssh.py	2009-11-25 07:27:43 +0000
@@ -638,12 +638,28 @@
                 'close_fds': True,
                 }
 
+import weakref
+_subproc_weakrefs = set()
+
+def _close_ssh_proc(proc):
+    for func in [proc.stdin.close, proc.stdout.close, proc.wait]:
+        try:
+            func()
+        except OSError:
+            pass
+
 
 class SSHSubprocess(object):
     """A socket-like object that talks to an ssh subprocess via pipes."""
 
     def __init__(self, proc):
         self.proc = proc
+        # Add a weakref to proc that will attempt to do the same as self.close
+        # to avoid leaving processes lingering indefinitely.
+        def terminate(ref):
+            _subproc_weakrefs.remove(ref)
+            _close_ssh_proc(proc)
+        _subproc_weakrefs.add(weakref.ref(self, terminate))
 
     def send(self, data):
         return os.write(self.proc.stdin.fileno(), data)
@@ -652,9 +668,7 @@
         return os.read(self.proc.stdout.fileno(), count)
 
     def close(self):
-        self.proc.stdin.close()
-        self.proc.stdout.close()
-        self.proc.wait()
+        _close_ssh_proc(self.proc)
 
     def get_filelike_channels(self):
         return (self.proc.stdout, self.proc.stdin)




More information about the bazaar-commits mailing list