From 46283a771c31324553ad820f010590edfea195ad Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Tue, 10 Sep 2013 19:05:37 +0900 Subject: Fix #2: Establish SSH connection in a thread-safe way Use an Event(), rather than a boolean, to determine whether or not the remote is connected. Protect the connection logic with a Lock(). Change-Id: Ifc5888894a90b7e3a11e21ec3f9bf69f0a7608a8 --- pygerrit/ssh.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'pygerrit') diff --git a/pygerrit/ssh.py b/pygerrit/ssh.py index 3e2add1..7728e48 100644 --- a/pygerrit/ssh.py +++ b/pygerrit/ssh.py @@ -25,6 +25,7 @@ from os.path import abspath, expanduser, isfile import re import socket +from threading import Event, Lock from .error import GerritError @@ -69,12 +70,11 @@ class GerritSSHClient(SSHClient): super(GerritSSHClient, self).__init__() self.remote_version = None self.hostname = hostname - self.connected = False + self.connected = Event() + self.lock = Lock() - def _connect(self): - """ Connect to the remote if not already connected. """ - if self.connected: - return + def _do_connect(self): + """ Connect to the remote. """ self.load_system_host_keys() configfile = expanduser("~/.ssh/config") if not isfile(configfile): @@ -103,7 +103,6 @@ class GerritSSHClient(SSHClient): port=port, username=data['user'], key_filename=key_filename) - self.connected = True except socket.error as e: raise GerritError("Failed to connect to server: %s" % e) @@ -114,6 +113,21 @@ class GerritSSHClient(SSHClient): except AttributeError: self.remote_version = None + def _connect(self): + """ Connect to the remote if not already connected. """ + if not self.connected.is_set(): + try: + self.lock.acquire() + # Another thread may have connected while we were + # waiting to acquire the lock + if not self.connected.is_set(): + self._do_connect() + self.connected.set() + except GerritError: + raise + finally: + self.lock.release() + def exec_command(self, command, bufsize=1, timeout=None, get_pty=False): """ Execute the command. -- cgit v1.2.1