[glib] GSocket – GSocketSource finalizing not threa dsafe on Windows



commit ab6b7dbc2efc506e43616941ac70f14fc20de574
Author: Sebastian Dröge <slomo circular-chaos org>
Date:   Sun Jul 28 16:43:44 2013 +0200

    GSocket – GSocketSource finalizing not threadsafe on Windows
    
    The requested_conditions list access is not threadsafe. When passing
    the socket ownership from a GSource callback to another thread, which
    also creates a GSocketSource for the socket, it can happen that the
    original GSocketSource is finalized at the same time as the new one
    is created. This would cause inconsistencies in the requested_conditions
    list and can cause assertions or completely undefined behaviour.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705027

 gio/gsocket.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
---
diff --git a/gio/gsocket.c b/gio/gsocket.c
index b606171..7f99a60 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -172,6 +172,7 @@ struct _GSocketPrivate
   int             current_errors;
   int             selected_events;
   GList          *requested_conditions; /* list of requested GIOCondition * */
+  GMutex          win32_source_lock;
 #endif
 
   struct {
@@ -759,6 +760,7 @@ g_socket_finalize (GObject *object)
     }
 
   g_assert (socket->priv->requested_conditions == NULL);
+  g_mutex_clear (&socket->priv->win32_source_lock);
 #endif
 
   for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++)
@@ -970,6 +972,7 @@ g_socket_init (GSocket *socket)
   socket->priv->construct_error = NULL;
 #ifdef G_OS_WIN32
   socket->priv->event = WSA_INVALID_EVENT;
+  g_mutex_init (&socket->priv->win32_source_lock);
 #endif
 }
 
@@ -3074,24 +3077,28 @@ static void
 add_condition_watch (GSocket      *socket,
                     GIOCondition *condition)
 {
+  g_mutex_lock (&socket->priv->win32_source_lock);
   g_assert (g_list_find (socket->priv->requested_conditions, condition) == NULL);
 
   socket->priv->requested_conditions =
     g_list_prepend (socket->priv->requested_conditions, condition);
 
   update_select_events (socket);
+  g_mutex_unlock (&socket->priv->win32_source_lock);
 }
 
 static void
 remove_condition_watch (GSocket      *socket,
                        GIOCondition *condition)
 {
+  g_mutex_lock (&socket->priv->win32_source_lock);
   g_assert (g_list_find (socket->priv->requested_conditions, condition) != NULL);
 
   socket->priv->requested_conditions =
     g_list_remove (socket->priv->requested_conditions, condition);
 
   update_select_events (socket);
+  g_mutex_unlock (&socket->priv->win32_source_lock);
 }
 
 static GIOCondition


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]