[project @ Arch-1:robey@lag.net--2005-master-shake%paramiko--dev--1--patch-34]
fix a comment claiming that channels are closed automatically when GC'd (they aren't and can't be); don't close the pipe until the app explicitly calls close(); signal EOF via the pipe
This commit is contained in:
parent
93f3cae64f
commit
f565576321
|
@ -87,7 +87,7 @@ class Channel (object):
|
|||
self.event = threading.Event()
|
||||
self.combine_stderr = False
|
||||
self.exit_status = -1
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Return a string representation of this object, for debugging.
|
||||
|
@ -454,24 +454,25 @@ class Channel (object):
|
|||
"""
|
||||
Close the channel. All future read/write operations on the channel
|
||||
will fail. The remote end will receive no more data (after queued data
|
||||
is flushed). Channels are automatically closed when they are garbage-
|
||||
collected, or when their L{Transport} is closed.
|
||||
is flushed). Channels are automatically closed when their L{Transport}
|
||||
is closed.
|
||||
|
||||
Note that because of peculiarities with the way python's garbage
|
||||
collection works on cycles, channels will B{not} be automatically
|
||||
closed by the garbage collector.
|
||||
"""
|
||||
self.lock.acquire()
|
||||
try:
|
||||
if not self.active or self.closed:
|
||||
return
|
||||
try:
|
||||
self._send_eof()
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_CLOSE))
|
||||
m.add_int(self.remote_chanid)
|
||||
self.transport._send_user_message(m)
|
||||
except EOFError:
|
||||
pass
|
||||
self._set_closed()
|
||||
# can't unlink from the Transport yet -- the remote side may still
|
||||
# try to send meta-data (exit-status, etc)
|
||||
self._close_internal()
|
||||
|
||||
# only close the pipe when the user explicitly closes the channel.
|
||||
# otherwise they will get unpleasant surprises.
|
||||
if self.pipe is not None:
|
||||
print 'closing pipe!'
|
||||
self.pipe.close()
|
||||
self.pipe = None
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
@ -862,7 +863,11 @@ class Channel (object):
|
|||
return
|
||||
|
||||
def _request_failed(self, m):
|
||||
self.close()
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self._close_internal()
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
def _feed(self, m):
|
||||
if type(m) is str:
|
||||
|
@ -980,20 +985,16 @@ class Channel (object):
|
|||
self.in_buffer_cv.notifyAll()
|
||||
self.in_stderr_buffer_cv.notifyAll()
|
||||
if self.pipe is not None:
|
||||
self.pipe.close()
|
||||
self.pipe = None
|
||||
self.pipe.set()
|
||||
finally:
|
||||
self.lock.release()
|
||||
self._log(DEBUG, 'EOF received')
|
||||
|
||||
def _handle_close(self, m):
|
||||
self.close()
|
||||
self.lock.acquire()
|
||||
try:
|
||||
self._close_internal()
|
||||
self.transport._unlink_channel(self.chanid)
|
||||
if self.pipe is not None:
|
||||
self.pipe.close()
|
||||
self.pipe = None
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
||||
|
@ -1023,6 +1024,22 @@ class Channel (object):
|
|||
self._log(DEBUG, 'EOF sent')
|
||||
return
|
||||
|
||||
def _close_internal(self):
|
||||
# you are holding the lock.
|
||||
if not self.active or self.closed:
|
||||
return
|
||||
try:
|
||||
self._send_eof()
|
||||
m = Message()
|
||||
m.add_byte(chr(MSG_CHANNEL_CLOSE))
|
||||
m.add_int(self.remote_chanid)
|
||||
self.transport._send_user_message(m)
|
||||
except EOFError:
|
||||
pass
|
||||
self._set_closed()
|
||||
# can't unlink from the Transport yet -- the remote side may still
|
||||
# try to send meta-data (exit-status, etc)
|
||||
|
||||
def _unlink(self):
|
||||
# server connection could die before we become active: still signal the close!
|
||||
if self.closed:
|
||||
|
|
Loading…
Reference in New Issue