##// END OF EJS Templates
sshpeer: add a develwarning if an sshpeer is not closed explicitly...
Valentin Gatien-Baron -
r47418:db8037e3 default
parent child Browse files
Show More
@@ -47,7 +47,7 b' class connectionpool(object):'
47 if util.safehasattr(peer, '_cleanup'):
47 if util.safehasattr(peer, '_cleanup'):
48
48
49 class mypeer(peer.__class__):
49 class mypeer(peer.__class__):
50 def _cleanup(self):
50 def _cleanup(self, warn=None):
51 # close pipee first so peer.cleanup reading it won't
51 # close pipee first so peer.cleanup reading it won't
52 # deadlock, if there are other processes with pipeo
52 # deadlock, if there are other processes with pipeo
53 # open (i.e. us).
53 # open (i.e. us).
@@ -148,14 +148,18 b' class doublepipe(object):'
148 return self._main.flush()
148 return self._main.flush()
149
149
150
150
151 def _cleanuppipes(ui, pipei, pipeo, pipee):
151 def _cleanuppipes(ui, pipei, pipeo, pipee, warn):
152 """Clean up pipes used by an SSH connection."""
152 """Clean up pipes used by an SSH connection."""
153 if pipeo:
153 didsomething = False
154 if pipeo and not pipeo.closed:
155 didsomething = True
154 pipeo.close()
156 pipeo.close()
155 if pipei:
157 if pipei and not pipei.closed:
158 didsomething = True
156 pipei.close()
159 pipei.close()
157
160
158 if pipee:
161 if pipee and not pipee.closed:
162 didsomething = True
159 # Try to read from the err descriptor until EOF.
163 # Try to read from the err descriptor until EOF.
160 try:
164 try:
161 for l in pipee:
165 for l in pipee:
@@ -165,6 +169,17 b' def _cleanuppipes(ui, pipei, pipeo, pipe'
165
169
166 pipee.close()
170 pipee.close()
167
171
172 if didsomething and warn is not None:
173 # Encourage explicit close of sshpeers. Closing via __del__ is
174 # not very predictable when exceptions are thrown, which has led
175 # to deadlocks due to a peer get gc'ed in a fork
176 # We add our own stack trace, because the stacktrace when called
177 # from __del__ is useless.
178 if False: # enabled in next commit
179 ui.develwarn(
180 b'missing close on SSH connection created at:\n%s' % warn
181 )
182
168
183
169 def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None):
184 def _makeconnection(ui, sshcmd, args, remotecmd, path, sshenv=None):
170 """Create an SSH connection to a server.
185 """Create an SSH connection to a server.
@@ -416,6 +431,7 b' class sshv1peer(wireprotov1peer.wirepeer'
416 self._pipee = stderr
431 self._pipee = stderr
417 self._caps = caps
432 self._caps = caps
418 self._autoreadstderr = autoreadstderr
433 self._autoreadstderr = autoreadstderr
434 self._initstack = b''.join(util.getstackframes(1))
419
435
420 # Commands that have a "framed" response where the first line of the
436 # Commands that have a "framed" response where the first line of the
421 # response contains the length of that response.
437 # response contains the length of that response.
@@ -456,10 +472,11 b' class sshv1peer(wireprotov1peer.wirepeer'
456 self._cleanup()
472 self._cleanup()
457 raise exception
473 raise exception
458
474
459 def _cleanup(self):
475 def _cleanup(self, warn=None):
460 _cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee)
476 _cleanuppipes(self.ui, self._pipei, self._pipeo, self._pipee, warn=warn)
461
477
462 __del__ = _cleanup
478 def __del__(self):
479 self._cleanup(warn=self._initstack)
463
480
464 def _sendrequest(self, cmd, args, framed=False):
481 def _sendrequest(self, cmd, args, framed=False):
465 if self.ui.debugflag and self.ui.configbool(
482 if self.ui.debugflag and self.ui.configbool(
@@ -611,7 +628,7 b' def makepeer(ui, path, proc, stdin, stdo'
611 try:
628 try:
612 protoname, caps = _performhandshake(ui, stdin, stdout, stderr)
629 protoname, caps = _performhandshake(ui, stdin, stdout, stderr)
613 except Exception:
630 except Exception:
614 _cleanuppipes(ui, stdout, stdin, stderr)
631 _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
615 raise
632 raise
616
633
617 if protoname == wireprototypes.SSHV1:
634 if protoname == wireprototypes.SSHV1:
@@ -637,7 +654,7 b' def makepeer(ui, path, proc, stdin, stdo'
637 autoreadstderr=autoreadstderr,
654 autoreadstderr=autoreadstderr,
638 )
655 )
639 else:
656 else:
640 _cleanuppipes(ui, stdout, stdin, stderr)
657 _cleanuppipes(ui, stdout, stdin, stderr, warn=None)
641 raise error.RepoError(
658 raise error.RepoError(
642 _(b'unknown version of SSH protocol: %s') % protoname
659 _(b'unknown version of SSH protocol: %s') % protoname
643 )
660 )
General Comments 0
You need to be logged in to leave comments. Login now