[gvfs/ftp-reorg: 11/15] [FTP] keep list of busy connections



commit d016610baa522dd5b2ab4fc1ca1a30ee6de69220
Author: Benjamin Otte <otte gnome org>
Date:   Fri Jun 5 10:49:48 2009 +0200

    [FTP] keep list of busy connections
    
    A busy connection is a connection that is currently used as a handle for
    a file transfer (upload or download). If all connections are busy, we
    can just return EBUSY instead of waiting for 30 seconds for a connection
    to become available.
    
    This is mostly useful for performance when there is a maximum of 1
    connection to the server and this connection is busy transferring a
    file. Even gio functions like g_file_copy() sometimes do additional
    operations while transferring files. (It does a query_info for the
    progress callback.)
---
 daemon/gvfsbackendftp.h |    1 +
 daemon/gvfsftptask.c    |   19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/daemon/gvfsbackendftp.h b/daemon/gvfsbackendftp.h
index ae58f7b..54ebb69 100644
--- a/daemon/gvfsbackendftp.h
+++ b/daemon/gvfsbackendftp.h
@@ -96,6 +96,7 @@ struct _GVfsBackendFtp
   GCond *        	cond;                   /* cond used to signal tasks waiting on the mutex */
   GQueue *        	queue;                  /* queue containing the connections */
   guint        		connections;            /* current number of connections */
+  guint                 busy_connections;       /* current number of connections being used for reads/writes */
   guint        		max_connections;        /* upper server limit for number of connections - dynamically generated */
 };
 
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
index e1fa92a..4c89d14 100644
--- a/daemon/gvfsftptask.c
+++ b/daemon/gvfsftptask.c
@@ -245,7 +245,8 @@ g_vfs_ftp_task_acquire_connection (GVfsFtpTask *task)
 
       g_get_current_time (&now);
       g_time_val_add (&now, G_VFS_FTP_TIMEOUT_IN_SECONDS * 1000 * 1000);
-      if (!g_cond_timed_wait (ftp->cond, ftp->mutex, &now))
+      if (ftp->busy_connections >= ftp->connections ||
+          !g_cond_timed_wait (ftp->cond, ftp->mutex, &now))
         {
           task->error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_BUSY,
         		                     _("The FTP server is busy. Try again later"));
@@ -419,6 +420,11 @@ g_vfs_ftp_task_give_connection (GVfsFtpTask *      task,
   g_return_if_fail (task->conn == NULL);
 
   task->conn = conn;
+  /* this connection is not busy anymore */
+  g_mutex_lock (task->backend->mutex);
+  g_assert (task->backend->busy_connections > 0);
+  task->backend->busy_connections--;
+  g_mutex_unlock (task->backend->mutex);
 }
 
 /**
@@ -436,6 +442,7 @@ GVfsFtpConnection *
 g_vfs_ftp_task_take_connection (GVfsFtpTask *task)
 {
   GVfsFtpConnection *conn;
+  GVfsBackendFtp *ftp;
 
   g_return_val_if_fail (task != NULL, NULL);
   g_return_val_if_fail (task->conn != NULL, NULL);
@@ -443,6 +450,16 @@ g_vfs_ftp_task_take_connection (GVfsFtpTask *task)
   conn = task->conn;
   task->conn = NULL;
 
+  ftp = task->backend;
+  /* mark this connection as busy */
+  g_mutex_lock (ftp->mutex);
+  ftp->busy_connections++;
+  /* if all connections are busy, signal all waiting threads, 
+   * so they stop waiting and return BUSY earlier */
+  if (ftp->busy_connections >= ftp->connections)
+    g_cond_broadcast (ftp->cond);
+  g_mutex_unlock (ftp->mutex);
+
   return conn;
 }
 



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