|
21 | 21 | from warnings import warn |
22 | 22 |
|
23 | 23 | from gevent import sleep, spawn, get_hub |
| 24 | +from gevent.lock import RLock |
24 | 25 | from ssh2.error_codes import LIBSSH2_ERROR_EAGAIN |
25 | 26 | from ssh2.exceptions import SFTPHandleError, SFTPProtocolError, \ |
26 | 27 | Timeout as SSH2Timeout |
@@ -127,6 +128,7 @@ def __init__(self, host, |
127 | 128 | identity_auth=identity_auth, |
128 | 129 | ) |
129 | 130 | proxy_host = '127.0.0.1' |
| 131 | + self._chan_lock = RLock() |
130 | 132 | super(SSHClient, self).__init__( |
131 | 133 | host, user=user, password=password, port=port, pkey=pkey, |
132 | 134 | num_retries=num_retries, retry_delay=retry_delay, |
@@ -291,10 +293,12 @@ def execute(self, cmd, use_pty=False, channel=None): |
291 | 293 | def _read_output_to_buffer(self, read_func, _buffer): |
292 | 294 | try: |
293 | 295 | while True: |
294 | | - size, data = read_func() |
| 296 | + with self._chan_lock: |
| 297 | + size, data = read_func() |
295 | 298 | while size == LIBSSH2_ERROR_EAGAIN: |
296 | 299 | self.poll() |
297 | | - size, data = read_func() |
| 300 | + with self._chan_lock: |
| 301 | + size, data = read_func() |
298 | 302 | if size <= 0: |
299 | 303 | break |
300 | 304 | _buffer.write(data) |
@@ -325,8 +329,9 @@ def wait_finished(self, host_output, timeout=None): |
325 | 329 | self.close_channel(channel) |
326 | 330 |
|
327 | 331 | def close_channel(self, channel): |
328 | | - logger.debug("Closing channel") |
329 | | - self._eagain(channel.close) |
| 332 | + with self._chan_lock: |
| 333 | + logger.debug("Closing channel") |
| 334 | + self._eagain(channel.close) |
330 | 335 |
|
331 | 336 | def _eagain(self, func, *args, **kwargs): |
332 | 337 | return self._eagain_errcode(func, LIBSSH2_ERROR_EAGAIN, *args, **kwargs) |
|
0 commit comments