|
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