vulkan/display: implement thread-safe find_window()
authorMatthew Waters <matthew@centricular.com>
Mon, 17 Feb 2020 04:05:49 +0000 (15:05 +1100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 3 Mar 2020 05:00:50 +0000 (05:00 +0000)
gst-libs/gst/vulkan/gstvkdisplay.c
gst-libs/gst/vulkan/gstvkdisplay.h

index 6f48eb4..530554a 100644 (file)
@@ -373,18 +373,58 @@ _compare_vulkan_window (GWeakRef * ref, GstVulkanWindow * window)
   return !equal;
 }
 
+static void
+prepend_window_weakref_item (GWeakRef * ref, GList ** new)
+{
+  GstVulkanWindow *window = g_weak_ref_get (ref);
+  if (window) {
+    *new = g_list_prepend (*new, window);
+  }
+}
+
 static GList *
-_find_window_list_item (GstVulkanDisplay * display, GstVulkanWindow * window)
+window_weak_list_to_strong (GstVulkanDisplay * display)
 {
-  GList *l;
+  GList *new = NULL;
+  g_list_foreach (display->windows, (GFunc) prepend_window_weakref_item, &new);
+  return new;
+}
 
-  if (!window)
-    return NULL;
+/**
+ * gst_vulkan_display_find_window:
+ * @display: a #GstVulkanDisplay
+ * @data: (closure): some data to pass to @compare_func
+ * @compare_func: (scope call): a comparison function to run
+ *
+ * Execute @compare_func over the list of windows stored by @display.  The
+ * first argument to @compare_func is the #GstVulkanWindow being checked and the
+ * second argument is @data.
+ *
+ * Returns: (transfer full): The first #GstVulkanWindow that causes a match
+ *          from @compare_func
+ *
+ * Since: 1.18
+ */
+GstVulkanWindow *
+gst_vulkan_display_find_window (GstVulkanDisplay * display, gpointer data,
+    GCompareFunc compare_func)
+{
+  GstVulkanWindow *ret = NULL;
+  GList *l, *windows;
 
-  l = g_list_find_custom (display->windows, window,
-      (GCompareFunc) _compare_vulkan_window);
+  GST_OBJECT_LOCK (display);
+  windows = window_weak_list_to_strong (display);
+  l = g_list_find_custom (windows, data, (GCompareFunc) compare_func);
+  if (l)
+    ret = gst_object_ref (l->data);
 
-  return l;
+  GST_DEBUG_OBJECT (display, "Found window %" GST_PTR_FORMAT
+      " (%p) in internal list", ret, ret);
+  GST_OBJECT_UNLOCK (display);
+
+  g_list_free_full (windows, gst_object_unref);
+
+  return ret;
 }
 
 /**
@@ -404,7 +444,8 @@ gst_vulkan_display_remove_window (GstVulkanDisplay * display,
   GList *l;
 
   GST_OBJECT_LOCK (display);
-  l = _find_window_list_item (display, window);
+  l = g_list_find_custom (display->windows, window,
+      (GCompareFunc) _compare_vulkan_window);
   if (l) {
     GWeakRef *ref = l->data;
     display->windows = g_list_delete_link (display->windows, l);
index 2a17eba..223c224 100644 (file)
@@ -131,7 +131,8 @@ gboolean                gst_vulkan_display_run_context_query        (GstElement
 /* GstVulkanWindow usage only */
 GST_VULKAN_API
 gboolean                gst_vulkan_display_remove_window            (GstVulkanDisplay * display, GstVulkanWindow * window);
-
+GST_VULKAN_API
+GstVulkanWindow *       gst_vulkan_display_find_window              (GstVulkanDisplay * display, gpointer data, GCompareFunc compare_func);
 
 G_END_DECLS