summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2009-06-05 10:49:48 +0200
committerBenjamin Otte <otte@gnome.org>2009-06-11 10:05:40 +0200
commit4cebb73a48341b3695bc34750eab7290dc44b629 (patch)
treefb06e88430665061296ae83834f85999c78b1a37
parent7428ea86b4c1f04ca6530d8eff4ca60cc8894f7e (diff)
downloadgvfs-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.h1
-rw-r--r--daemon/gvfsftptask.c19
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;
}