[gvfs] Keep track of connection usability for new commands
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gvfs] Keep track of connection usability for new commands
- Date: Thu, 3 Sep 2009 17:15:16 +0000 (UTC)
commit b0e4bdf15c0f81d14616173177e28354abf6e560
Author: Benjamin Otte <otte gnome org>
Date: Thu Sep 3 19:07:27 2009 +0200
Keep track of connection usability for new commands
Add a waiting_for_reply boolean flag to the connection. Set it when
sending a request to the server, clear it after receiving a reply.
When trying to push the connection into the connection pool, only allow
that when it is not waiting for a reply.
This way we fix the case where the task was cancelled while waiting for
the reply. It would then ignore the reply and happily push the connection
with the pending reply back into the pool, leaving the next one to use
it with a stale reply. You can imagine the hilarity that happened from
this.
Also, g_return_if_fail() if trying to send a command when waiting for a
reply or when trying to receive a command while not waiting.
If it turns out I overlooked a valid case where this can happen, we
need to remove those checks. So far I didn't find any.
daemon/gvfsftpconnection.c | 25 ++++++++++++++++++++-----
1 files changed, 20 insertions(+), 5 deletions(-)
---
diff --git a/daemon/gvfsftpconnection.c b/daemon/gvfsftpconnection.c
index bdb96bd..14a9148 100644
--- a/daemon/gvfsftpconnection.c
+++ b/daemon/gvfsftpconnection.c
@@ -38,6 +38,7 @@ struct _GVfsFtpConnection
GIOStream * commands; /* ftp command stream */
GDataInputStream * commands_in; /* wrapper around in stream to allow line-wise reading */
+ gboolean waiting_for_reply; /* TRUE if a command was sent but no reply received yet */
GSocket * listen_socket; /* socket we are listening on for active FTP connections */
GIOStream * data; /* ftp data stream or NULL if not in use */
@@ -87,6 +88,8 @@ g_vfs_ftp_connection_new (GSocketConnectable *addr,
enable_keepalive (G_SOCKET_CONNECTION (conn->commands));
conn->commands_in = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (conn->commands)));
g_data_input_stream_set_newline_type (conn->commands_in, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
+ /* The first thing that needs to happen is receiving the welcome message */
+ conn->waiting_for_reply = TRUE;
return conn;
}
@@ -124,6 +127,7 @@ g_vfs_ftp_connection_send (GVfsFtpConnection *conn,
GError ** error)
{
g_return_val_if_fail (conn != NULL, FALSE);
+ g_return_val_if_fail (!conn->waiting_for_reply, FALSE);
g_return_val_if_fail (command != NULL, FALSE);
g_return_val_if_fail (len >= -1, FALSE);
if (len < 0)
@@ -135,6 +139,7 @@ g_vfs_ftp_connection_send (GVfsFtpConnection *conn,
else
g_debug ("--%2d -> %s", conn->debug_id, command);
+ conn->waiting_for_reply = TRUE;
return g_output_stream_write_all (g_io_stream_get_output_stream (conn->commands),
command,
len,
@@ -158,7 +163,8 @@ g_vfs_ftp_connection_receive (GVfsFtpConnection *conn,
GPtrArray *lines;
guint response = 0;
- g_return_val_if_fail (conn != NULL, FALSE);
+ g_return_val_if_fail (conn != NULL, 0);
+ g_return_val_if_fail (conn->waiting_for_reply, 0);
if (reply)
lines = g_ptr_array_new_with_free_func (g_free);
@@ -222,6 +228,13 @@ g_vfs_ftp_connection_receive (GVfsFtpConnection *conn,
g_ptr_array_add (lines, NULL);
*reply = (char **) g_ptr_array_free (lines, FALSE);
}
+
+ /* 1xx commands are intermediate commands and require a further
+ * message from the server to complete
+ */
+ if (response >= 200)
+ conn->waiting_for_reply = FALSE;
+
return response;
fail:
@@ -450,9 +463,10 @@ g_vfs_ftp_connection_get_data_stream (GVfsFtpConnection *conn)
* g_vfs_ftp_connection_is_usable:
* @conn: a connection
*
- * Checks if this connection can still be used to send new commands. For
- * example, if the connection was closed, this is not possible and this
- * function will return %FALSE.
+ * Checks if this connection can be used to send new commands. For
+ * example, if the connection is in the process of a command sequence or
+ * if the connection was closed, this is not possible and this function
+ * will return %FALSE.
*
* Returns: %TRUE if the connection is still usable
**/
@@ -463,7 +477,8 @@ g_vfs_ftp_connection_is_usable (GVfsFtpConnection *conn)
g_return_val_if_fail (conn != NULL, FALSE);
- /* FIXME: return FALSE here if a send or receive failed irrecoverably */
+ if (conn->waiting_for_reply)
+ return FALSE;
cond = G_IO_ERR | G_IO_HUP;
cond = g_socket_condition_check (g_socket_connection_get_socket (G_SOCKET_CONNECTION (conn->commands)), cond);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]