[gnome-network-displays/benzea/fix-p2p-sink-removal] meta-provider: Fix sink removal in case matches are gone




commit d82d3d375174ea70cbfb6208405e7070bbacd1fd
Author: Benjamin Berg <bberg redhat com>
Date:   Tue Oct 13 15:53:56 2020 +0200

    meta-provider: Fix sink removal in case matches are gone
    
    It may (currently) happen that a sink is reporting incorrect matches at
    the time it is removed. In that case, we will not find it in the hash
    table, causing us to not find the corresponding meta sink.
    
    Fix this by just doing a linear search for the meta sink that contains
    the sink.
    
    This probably means the fix from 23164b58f4d5 (p2p-sink: Guard against
    returning NULL as possible match string) is not needed anymore. i.e.
    that commit, while fixing a problem, did not address the original crash.
    
    Fixes: #160

 src/nd-meta-provider.c | 20 ++++++++++----------
 src/nd-meta-sink.c     | 17 +++++++++++++++++
 src/nd-meta-sink.h     |  2 ++
 3 files changed, 29 insertions(+), 10 deletions(-)
---
diff --git a/src/nd-meta-provider.c b/src/nd-meta-provider.c
index f229b2d..c84f7fd 100644
--- a/src/nd-meta-provider.c
+++ b/src/nd-meta-provider.c
@@ -127,21 +127,21 @@ provider_sink_removed_cb (NdMetaProvider *meta_provider, NdSink *sink, NdProvide
 {
   g_autoptr(GPtrArray) sink_matches = NULL;
   NdMetaSink *meta_sink = NULL;
+  guint idx = 0;
 
   g_object_get (sink, "matches", &sink_matches, NULL);
   g_assert (sink_matches != NULL);
 
-  for (gint i = 0; i < sink_matches->len; i++)
-    {
-      gchar *match = sink_matches->pdata[i];
-
-      /* Find the first matching meta sink and remove any match*/
-      if (meta_sink == NULL)
-        meta_sink = g_hash_table_lookup (meta_provider->deduplicate, match);
-
-      g_hash_table_remove (meta_provider->deduplicate, match);
-    }
+  /* Search all known meta sinks for the matching one.
+   * Note that we really need to search for it rather than doing
+   * a faster lookup, as sink that is removed may not be reporting
+   * its matches correctly anymore. */
+  g_assert (g_ptr_array_find_with_equal_func (meta_provider->sinks,
+                                              sink,
+                                              (GEqualFunc) nd_meta_sink_has_sink,
+                                              &idx));
 
+  meta_sink = g_ptr_array_index (meta_provider->sinks, idx);
   g_assert (meta_sink != NULL);
   if (nd_meta_sink_remove_sink (meta_sink, sink))
     {
diff --git a/src/nd-meta-sink.c b/src/nd-meta-sink.c
index d5ed075..18f3ab8 100644
--- a/src/nd-meta-sink.c
+++ b/src/nd-meta-sink.c
@@ -359,6 +359,23 @@ nd_meta_sink_remove_sink (NdMetaSink *meta_sink,
   return meta_sink->sinks->len <= 0;
 }
 
+/**
+ * nd_meta_sink_has_sink
+ * @meta_sink: a #NdMetaSink
+ * @sink: a #NdSink
+ *
+ * Checks whether meta sink contains the given sink as a child sink.
+ *
+ * Returns:
+ *   Whether @sink is contained in @meta_sink.
+ */
+gboolean
+nd_meta_sink_has_sink (NdMetaSink *meta_sink,
+                       NdSink     *sink)
+{
+  return g_ptr_array_find (meta_sink->sinks, sink, NULL);
+}
+
 NdMetaSink *
 nd_meta_sink_new (NdSink *sink)
 {
diff --git a/src/nd-meta-sink.h b/src/nd-meta-sink.h
index 54eb59e..4c3d2ce 100644
--- a/src/nd-meta-sink.h
+++ b/src/nd-meta-sink.h
@@ -32,6 +32,8 @@ void                  nd_meta_sink_add_sink (NdMetaSink *meta_sink,
                                              NdSink     *sink);
 gboolean              nd_meta_sink_remove_sink (NdMetaSink *meta_sink,
                                                 NdSink     *sink);
+gboolean              nd_meta_sink_has_sink (NdMetaSink *meta_sink,
+                                             NdSink     *sink);
 
 
 G_END_DECLS


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