[X2go-Commits] python-x2go.git - master (branch) updated: 0.1.1.4-253-g469afde

X2Go dev team git-admin at x2go.org
Mon May 28 16:55:32 CEST 2012


The branch, master has been updated
       via  469afde919074790f53328b0f2fc3fd8f2971ea8 (commit)
      from  144f7a489ea5aefcb13aca8a619438f329da3a66 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 469afde919074790f53328b0f2fc3fd8f2971ea8
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Mon May 28 16:55:11 2012 +0200

    Use proper locking of session actions that are critical to being executed in parallel.

-----------------------------------------------------------------------

Summary of changes:
 debian/changelog                  |    2 +
 x2go/backends/control/_stdout.py  |   93 ++++++++++++++++++++++---------------
 x2go/backends/terminal/_stdout.py |   11 ++--
 3 files changed, 62 insertions(+), 44 deletions(-)

The diff of changes is:
diff --git a/debian/changelog b/debian/changelog
index 4a70238..89fff6d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -140,6 +140,8 @@ python-x2go (0.1.2.0-0~x2go1) UNRELEASED; urgency=low
       keyboard layout _and_ the keyboard variant from the client-side.
     - Give functionality to the ,,setdpi'' and the ,,dpi'' session profile
       parameter (setting the DPI allows font scaling).
+    - Use proper locking of session actions that are critical to being executed
+      in parallel.
   * Depend on python-xlib.
 
  -- Mike Gabriel <mike.gabriel at das-netzwerkteam.de>  Sat, 28 Sep 2012 01:44:21 +0100
diff --git a/x2go/backends/control/_stdout.py b/x2go/backends/control/_stdout.py
index e249cc4..f9be7da 100644
--- a/x2go/backends/control/_stdout.py
+++ b/x2go/backends/control/_stdout.py
@@ -35,6 +35,7 @@ import string
 import random
 import re
 import locale
+import threading
 
 from gevent import socket
 
@@ -127,8 +128,6 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         self._server_features = None
 
-        self.locked = False
-
         if logger is None:
             self.logger = log.X2goLogger(loglevel=loglevel)
         else:
@@ -155,6 +154,8 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         self.published_applications_no_submenus = published_applications_no_submenus
         self._already_querying_published_applications = False
 
+        self._transport_lock = threading.Lock()
+
     def get_hostname(self):
         return self.hostname
 
@@ -172,41 +173,57 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
     def _x2go_sftp_put(self, local_path, remote_path):
 
-        self.logger('sFTP-put: %s -> %s:%s' % (os.path.normpath(local_path), self.remote_peername(), remote_path), loglevel=log.loglevel_DEBUG)
-        try:
-            while self.sftp_client is None:
-                gevent.sleep(.1)
-            self.sftp_client.put(os.path.normpath(local_path), remote_path)
-        except x2go_exceptions.SSHException:
-            # react to connection dropped error for SSH connections
-            raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an SFTP put action.')
+        ssh_transport = self.get_transport()
+        self._transport_lock.acquire()
+        if ssh_transport and ssh_transport.is_authenticated():
+            self.logger('sFTP-put: %s -> %s:%s' % (os.path.normpath(local_path), self.remote_peername(), remote_path), loglevel=log.loglevel_DEBUG)
+            self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+            try:
+                self.sftp_client.put(os.path.normpath(local_path), remote_path)
+            except x2go_exceptions.SSHException, socket.error:
+                # react to connection dropped error for SSH connections
+                self._transport_lock.release()
+                raise x2go_exceptions.X2goControlSessionException('The SSH connection was dropped during an SFTP put action.')
+            self.sftp_client = None
+        self._transport_lock.release()
 
     def _x2go_sftp_write(self, remote_path, content):
 
-        self.logger('sFTP-write: opening remote file %s on host %s for writing' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
-        try:
-            while self.sftp_client is None:
-                gevent.sleep(.1)
-            remote_fileobj = self.sftp_client.open(remote_path, 'w')
-            self.logger('sFTP-write: writing content: %s' % content, loglevel=log.loglevel_DEBUG_SFTPXFER)
-            remote_fileobj.write(content)
-            remote_fileobj.close()
-        except x2go_exceptions.SSHException:
-            self.logger('sFTP-write: opening remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
+        ssh_transport = self.get_transport()
+        self._transport_lock.acquire()
+        if ssh_transport and ssh_transport.is_authenticated():
+            self.logger('sFTP-write: opening remote file %s on host %s for writing' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
+            self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+            try:
+                remote_fileobj = self.sftp_client.open(remote_path, 'w')
+                self.logger('sFTP-write: writing content: %s' % content, loglevel=log.loglevel_DEBUG_SFTPXFER)
+                remote_fileobj.write(content)
+                remote_fileobj.close()
+            except x2go_exceptions.SSHException, socket.error:
+                self._transport_lock.release()
+                self.logger('sFTP-write: opening remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
+            self.sftp_client = None
+        self._transport_lock.release()
 
     def _x2go_sftp_remove(self, remote_path):
 
-        self.logger('sFTP-write: removing remote file %s on host %s' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
-        while self.sftp_client is None:
-            gevent.sleep(.1)
-        self.sftp_client.remove(remote_path)
+        ssh_transport = self.get_transport()
+        self._transport_lock.acquire()
+        if ssh_transport and ssh_transport.is_authenticated():
+            self.logger('sFTP-write: removing remote file %s on host %s' % (remote_path, self.remote_peername()), loglevel=log.loglevel_DEBUG)
+            self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
+            try:
+                self.sftp_client.remove(remote_path)
+            except x2go_exceptions.SSHException, socket.error:
+                self._transport_lock.release()
+                self.logger('sFTP-write: removing remote file %s on host %s failed' % (remote_path, self.remote_peername()), loglevel=log.loglevel_WARN)
+            self.sftp_client = None
+            self._transport_lock.release()
 
     def _x2go_exec_command(self, cmd_line, loglevel=log.loglevel_INFO, timeout=20, **kwargs):
 
-        while self.locked:
-            gevent.sleep(.1)
+        self._transport_lock.acquire()
 
-        self.locked = True
         _retval = None
 
         if type(cmd_line) == types.ListType:
@@ -214,11 +231,10 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
         else:
             cmd = cmd_line
         ssh_transport = self.get_transport()
-        if ssh_transport is not None:
+        if ssh_transport and ssh_transport.is_authenticated():
 
             timer = gevent.Timeout(timeout)
             timer.start()
-            self.sftp_client = None
             try:
                 self.logger("executing command on X2Go server ,,%s'': %s" % (self.profile_name, _rerewrite_blanks(cmd)), loglevel)
                 _retval = self.exec_command(_rewrite_password(cmd, user=self.get_transport().get_username(), password=self._session_password), **kwargs)
@@ -226,42 +242,40 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
                 self.session_died = True
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self.locked = False
+                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except EOFError:
                 self.session_died = True
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self.locked = False
+                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except x2go_exceptions.SSHException:
                 self.session_died = True
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self.locked = False
+                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             except gevent.timeout.Timeout:
                 self.session_died = True
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self.locked = False
+                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session command timed out')
             except socket.error:
                 self.session_died = True
                 if self.sshproxy_session:
                     self.sshproxy_session.stop_thread()
-                self.locked = False
+                self._transport_lock.release()
                 raise x2go_exceptions.X2goControlSessionException('the X2Go control session has died unexpectedly')
             finally:
-                self.locked = False
                 timer.cancel()
-                self.sftp_client = paramiko.SFTPClient.from_transport(ssh_transport)
 
         else:
-            self.locked = False
             raise x2go_exceptions.X2goControlSessionException('the X2Go control session is not connected')
-        return _retval
 
+        self._transport_lock.release()
+        return _retval
 
     @property
     def _x2go_server_features(self):
@@ -598,6 +612,9 @@ class X2goControlSessionSTDOUT(paramiko.SSHClient):
 
         self._session_auth_rsakey = None
 
+        # in any case, release out internal transport lock
+        self._transport_lock.release()
+
         try:
             if self.get_transport() is not None:
                 still_active = self.get_transport().is_active()
diff --git a/x2go/backends/terminal/_stdout.py b/x2go/backends/terminal/_stdout.py
index ce80d32..066db33 100644
--- a/x2go/backends/terminal/_stdout.py
+++ b/x2go/backends/terminal/_stdout.py
@@ -33,6 +33,7 @@ import gevent
 import cStringIO
 import copy
 import shutil
+import threading
 
 # Python X2Go modules
 import x2go.rforward as rforward
@@ -339,6 +340,7 @@ class X2goTerminalSessionSTDOUT(object):
         else:
             self.session_info = info_backend()
 
+        self._share_local_folder_lock = threading.Lock()
         self._cleaned_up = False
 
     def __del__(self):
@@ -698,9 +700,7 @@ class X2goTerminalSessionSTDOUT(object):
         _x2go_key_bundle = _tmp_io_object.getvalue()
 
         # if there is another call to this method currently being processed, wait for that one to finish
-        while self._share_local_folder_busy:
-            gevent.sleep(.1)
-        self._share_local_folder_busy = True
+        self._share_local_folder_lock.acquire()
 
         try:
             self.control_session._x2go_sftp_write(_x2go_key_fname, _x2go_key_bundle)
@@ -762,10 +762,9 @@ class X2goTerminalSessionSTDOUT(object):
             self.logger('x2gomountdirs output is: %s' % _stdout, log.loglevel_NOTICE)
 
         except:
+            self._share_local_folder_lock.release()
             raise
-        finally:
-            # allow sharing of other folders again
-            self._share_local_folder_busy = False
+        self._share_local_folder_lock.release()
 
         if len(_stdout) >= 6 and _stdout[5].endswith('ok'):
             return True


hooks/post-receive
-- 
python-x2go.git (Python X2Go Client API)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-x2go.git" (Python X2Go Client API).




More information about the x2go-commits mailing list