diff options
author | Benjamin Otte <otte@gnome.org> | 2009-06-05 10:49:48 +0200 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2009-06-11 10:05:40 +0200 |
commit | 4cebb73a48341b3695bc34750eab7290dc44b629 (patch) | |
tree | fb06e88430665061296ae83834f85999c78b1a37 | |
parent | 7428ea86b4c1f04ca6530d8eff4ca60cc8894f7e (diff) | |
download | gvfs-4cebb73a48341b3695bc34750eab7290dc44b629.tar.gz |
[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.)
-rw-r--r-- | daemon/gvfsbackendftp.h | 1 | ||||
-rw-r--r-- | daemon/gvfsftptask.c | 19 |
2 files changed, 19 insertions, 1 deletions
diff --git a/daemon/gvfsbackendftp.h b/daemon/gvfsbackendftp.h index ae58f7b4..54ebb696 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 e1fa92a2..4c89d142 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; } |