[gvfs/gnome-3-12] afp: Fix race between writing and reading



commit ee7c6013110545d9f1bd5533e7c1090783de4425
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 58291f8..62bf76a 100644
--- a/daemon/gvfsafpconnection.c
+++ b/daemon/gvfsafpconnection.c
@@ -1264,6 +1264,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); \
@@ -1283,11 +1286,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);
@@ -1311,10 +1309,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);
@@ -1429,6 +1423,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]