[glib/mcatanzaro/gresolver-reload] gresolver: add missing locking




commit be8e85fc3ada40e769b0d2a972b2aa0075a5101b
Author: Michael Catanzaro <mcatanzaro redhat com>
Date:   Mon Nov 22 15:20:18 2021 -0600

    gresolver: add missing locking
    
    This is sad, but GResolver has one member variable for historical
    reasons, to implement the reload signal. Since it offers a global
    singleton, we should make sure it's really safe to use from multiple
    threads at once.

 gio/gresolver.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)
---
diff --git a/gio/gresolver.c b/gio/gresolver.c
index 6dafa9e1e..91ef19f73 100644
--- a/gio/gresolver.c
+++ b/gio/gresolver.c
@@ -64,6 +64,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 struct _GResolverPrivate {
 #ifdef G_OS_UNIX
+  GMutex mutex;
   time_t resolv_conf_timestamp;
 #else
   int dummy;
@@ -148,9 +149,27 @@ g_resolver_real_lookup_service_finish (GResolver            *resolver,
   return srv_records_to_targets (records);
 }
 
+#ifdef G_OS_UNIX
+static void
+g_resolver_finalize (GObject *object)
+{
+  GResolver *resolver = G_RESOLVER (object);
+
+  g_mutex_clear (&resolver->priv->mutex);
+
+  G_OBJECT_CLASS (g_resolver_parent_class)->finalize (object);
+}
+#endif
+
 static void
 g_resolver_class_init (GResolverClass *resolver_class)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (resolver_class);
+
+#ifdef G_OS_UNIX
+  object_class->finalize = g_resolver_finalize;
+#endif
+
   /* Automatically pass these over to the lookup_records methods */
   resolver_class->lookup_service = g_resolver_real_lookup_service;
   resolver_class->lookup_service_async = g_resolver_real_lookup_service_async;
@@ -193,6 +212,8 @@ g_resolver_init (GResolver *resolver)
 #ifdef G_OS_UNIX
   if (stat (_PATH_RESCONF, &st) == 0)
     resolver->priv->resolv_conf_timestamp = st.st_mtime;
+
+  g_mutex_init (&resolver->priv->mutex);
 #endif
 }
 
@@ -258,11 +279,15 @@ maybe_emit_reload (GResolver *resolver)
 
   if (stat (_PATH_RESCONF, &st) == 0)
     {
+      g_mutex_lock (&resolver->priv->mutex);
       if (st.st_mtime != resolver->priv->resolv_conf_timestamp)
         {
           resolver->priv->resolv_conf_timestamp = st.st_mtime;
+          g_mutex_unlock (&resolver->priv->mutex);
           g_signal_emit (resolver, signals[RELOAD], 0);
         }
+      else
+        g_mutex_unlock (&resolver->priv->mutex);
     }
 #endif
 }
@@ -1210,15 +1235,21 @@ g_resolver_lookup_records_finish (GResolver     *resolver,
 guint64
 g_resolver_get_serial (GResolver *resolver)
 {
+  guint64 result;
+
   g_return_val_if_fail (G_IS_RESOLVER (resolver), 0);
 
   maybe_emit_reload (resolver);
 
 #ifdef G_OS_UNIX
-  return (guint64) resolver->priv->resolv_conf_timestamp;
+  g_mutex_lock (&resolver->priv->mutex);
+  result = resolver->priv->resolv_conf_timestamp;
+  g_mutex_unlock (&resolver->priv->mutex);
 #else
-  return 1;
+  result = 1;
 #endif
+
+  return result;
 }
 
 /**


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