summaryrefslogtreecommitdiff
path: root/daemon/gvfsafpconnection.c
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2014-07-13 22:43:27 +0100
committerRoss Lagerwall <rosslagerwall@gmail.com>2014-07-17 17:49:26 +0100
commit66582af10b29f5a94a8d437173ae396bbce84406 (patch)
treea2dfd592c16249999efaf3f7994a6afde7dc77b1 /daemon/gvfsafpconnection.c
parentf1dbbb14162fe458b1f374ef888ffab9e15bc1ae (diff)
downloadgvfs-66582af10b29f5a94a8d437173ae396bbce84406.tar.gz
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
Diffstat (limited to 'daemon/gvfsafpconnection.c')
-rw-r--r--daemon/gvfsafpconnection.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index 7af4c089..9e81b725 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,