diff options
Diffstat (limited to 'paramiko/channel.py')
-rw-r--r-- | paramiko/channel.py | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py index 910a03c..4694eef 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -1,4 +1,4 @@ -# Copyright (C) 2003-2007 Robey Pointer <robey@lag.net> +# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com> # # This file is part of paramiko. # @@ -90,6 +90,7 @@ class Channel (object): self.logger = util.get_logger('paramiko.transport') self._pipe = None self.event = threading.Event() + self.event_ready = False self.combine_stderr = False self.exit_status = -1 self.origin_addr = None @@ -152,7 +153,7 @@ class Channel (object): # pixel height, width (usually useless) m.add_int(0).add_int(0) m.add_string('') - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() @@ -179,7 +180,7 @@ class Channel (object): m.add_int(self.remote_chanid) m.add_string('shell') m.add_boolean(1) - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() @@ -207,7 +208,7 @@ class Channel (object): m.add_string('exec') m.add_boolean(True) m.add_string(command) - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() @@ -234,7 +235,7 @@ class Channel (object): m.add_string('subsystem') m.add_boolean(True) m.add_string(subsystem) - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() @@ -261,7 +262,7 @@ class Channel (object): m.add_int(width) m.add_int(height) m.add_int(0).add_int(0) - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() @@ -291,10 +292,8 @@ class Channel (object): @since: 1.2 """ - while True: - if self.closed or self.status_event.isSet(): - break - self.status_event.wait(0.1) + self.status_event.wait() + assert self.status_event.isSet() return self.exit_status def send_exit_status(self, status): @@ -376,7 +375,7 @@ class Channel (object): m.add_string(auth_protocol) m.add_string(auth_cookie) m.add_int(screen_number) - self.event.clear() + self._event_pending() self.transport._send_user_message(m) self._wait_for_event() self.transport._set_x11_handler(handler) @@ -919,9 +918,10 @@ class Channel (object): self.out_max_packet_size = max(max_packet_size, MIN_PACKET_SIZE) self.active = 1 self._log(DEBUG, 'Max packet out: %d bytes' % max_packet_size) - + def _request_success(self, m): self._log(DEBUG, 'Sesch channel %d request ok' % self.chanid) + self.event_ready = True self.event.set() return @@ -1069,17 +1069,19 @@ class Channel (object): def _log(self, level, msg, *args): self.logger.log(level, "[chan " + self._name + "] " + msg, *args) + def _event_pending(self): + self.event.clear() + self.event_ready = False + def _wait_for_event(self): - while True: - self.event.wait(0.1) - if self.event.isSet(): - return - if self.closed: - e = self.transport.get_exception() - if e is None: - e = SSHException('Channel closed.') - raise e - return + self.event.wait() + assert self.event.isSet() + if self.event_ready: + return + e = self.transport.get_exception() + if e is None: + e = SSHException('Channel closed.') + raise e def _set_closed(self): # you are holding the lock. @@ -1087,6 +1089,9 @@ class Channel (object): self.in_buffer.close() self.in_stderr_buffer.close() self.out_buffer_cv.notifyAll() + # Notify any waiters that we are closed + self.event.set() + self.status_event.set() if self._pipe is not None: self._pipe.set_forever() |