[gvfs] Make this code more robust against quickly opening connections



commit f1c2079b78c8424b83d758f88bfe16027a415b42
Author: Benjamin Otte <otte gnome org>
Date:   Thu Sep 3 19:05:25 2009 +0200

    Make this code more robust against quickly opening connections
    
    - Don't assume a new connection failed when it was cancelled
    - Only update max_connections when we're the only thread that opened a
      new connection.

 daemon/gvfsftptask.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)
---
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
index d236ef8..4cabf14 100644
--- a/daemon/gvfsftptask.c
+++ b/daemon/gvfsftptask.c
@@ -209,6 +209,7 @@ g_vfs_ftp_task_acquire_connection (GVfsFtpTask *task)
 
       if (ftp->connections < ftp->max_connections)
         {
+          static GThread *last_thread = NULL;
           /* Save current number of connections here, so we can limit maximum
            * connections later.
            * This is necessary for threading reasons (connections can be
@@ -216,6 +217,7 @@ g_vfs_ftp_task_acquire_connection (GVfsFtpTask *task)
           guint maybe_max_connections = ftp->connections;
 
           ftp->connections++;
+          last_thread = g_thread_self ();
           g_mutex_unlock (ftp->mutex);
           task->conn = g_vfs_ftp_connection_new (ftp->addr, task->cancellable, &task->error);
           if (G_LIKELY (task->conn != NULL))
@@ -227,19 +229,27 @@ g_vfs_ftp_task_acquire_connection (GVfsFtpTask *task)
                 break;
             }
 
-          g_vfs_ftp_task_clear_error (task);
           g_vfs_ftp_connection_free (task->conn);
           task->conn = NULL;
           g_mutex_lock (ftp->mutex);
           ftp->connections--;
-          ftp->max_connections = MIN (ftp->max_connections, maybe_max_connections);
-          if (ftp->max_connections == 0)
+          /* If this value is still equal to our thread it means there were no races 
+           * trying to open connections and the maybe_max_connections value is 
+           * reliable. */
+          if (last_thread == g_thread_self () && 
+              !g_vfs_ftp_task_error_matches (task, G_IO_ERROR, G_IO_ERROR_CANCELLED))
             {
-              g_debug ("no more connections left, exiting...\n");
-              /* FIXME: shut down properly */
-              exit (0);
+              g_print ("maybe: %u, max %u (due to %s)\n", maybe_max_connections, ftp->max_connections, task->error->message);
+              ftp->max_connections = MIN (ftp->max_connections, maybe_max_connections);
+              if (ftp->max_connections == 0)
+                {
+                  g_debug ("no more connections left, exiting...\n");
+                  /* FIXME: shut down properly */
+                  exit (0);
+                }
             }
 
+          g_vfs_ftp_task_clear_error (task);
           continue;
         }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]