[gvfs] afp: Fix race between writing and reading
- From: Ross Lagerwall <rossl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: Fix race between writing and reading
- Date: Thu, 17 Jul 2014 16:49:29 +0000 (UTC)
commit 66582af10b29f5a94a8d437173ae396bbce84406
Author: Ross Lagerwall <rosslagerwall gmail com>
Date: Sun Jul 13 22:43:27 2014 +0100
afp: Fix race between writing and reading
The following sequence of events is possible in GVfsAfpConnection:
send_request_unlocked
write_dsi_header_cb
... return to main loop ...
read_dsi_header_cb
write_command_cb
This happens if the server sends its response before the main loop gets
a chance to run since write_command_cb is executed asynchronously as an
idle function. It causes the job to hang because the request is only
stored in the request hash table in write_command_cb and so the response
is ignored when being processed because it cannot find the corresponding
request.
To fix this, store the request in the hash table before the request is
written.
https://bugzilla.gnome.org/show_bug.cgi?id=733133
daemon/gvfsafpconnection.c | 16 +++++++---------
1 files changed, 7 insertions(+), 9 deletions(-)
---
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index 7af4c08..9e81b72 100644
--- a/daemon/gvfsafpconnection.c
+++ b/daemon/gvfsafpconnection.c
@@ -1265,6 +1265,9 @@ write_all_finish (GOutputStream *stream,
} \
\
g_error_free (err); \
+\
+ g_hash_table_remove (priv->request_hash, \
+ GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID))); \
free_request_data (req_data); \
\
g_mutex_lock (&priv->mutex); \
@@ -1284,11 +1287,6 @@ write_buf_cb (GObject *object, GAsyncResult *res, gpointer user_data)
HANDLE_RES ();
- g_hash_table_insert (priv->request_hash,
- GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
- req_data);
-
-
g_mutex_lock (&priv->mutex);
send_request_unlocked (afp_conn);
g_mutex_unlock (&priv->mutex);
@@ -1312,10 +1310,6 @@ write_command_cb (GObject *object, GAsyncResult *res, gpointer user_data)
return;
}
- g_hash_table_insert (priv->request_hash,
- GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
- req_data);
-
g_mutex_lock (&priv->mutex);
send_request_unlocked (afp_conn);
g_mutex_unlock (&priv->mutex);
@@ -1430,6 +1424,10 @@ send_request_unlocked (GVfsAfpConnection *afp_connection)
g_assert_not_reached ();
}
+ if (req_data->type != REQUEST_TYPE_TICKLE)
+ g_hash_table_insert (priv->request_hash,
+ GUINT_TO_POINTER ((guint)GUINT16_FROM_BE (priv->write_dsi_header.requestID)),
+ req_data);
write_all_async (g_io_stream_get_output_stream (priv->stream),
&priv->write_dsi_header, sizeof (DSIHeader), 0,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]