From af19fa94f45c3d20ee5f77faefc35c6fec3c6db6 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 17 Feb 2020 15:05:49 +1100 Subject: [PATCH] vulkan/display: implement thread-safe find_window() --- gst-libs/gst/vulkan/gstvkdisplay.c | 59 +++++++++++++++++++++++++----- gst-libs/gst/vulkan/gstvkdisplay.h | 3 +- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/vulkan/gstvkdisplay.c b/gst-libs/gst/vulkan/gstvkdisplay.c index 6f48eb4b78..530554a9a8 100644 --- a/gst-libs/gst/vulkan/gstvkdisplay.c +++ b/gst-libs/gst/vulkan/gstvkdisplay.c @@ -373,18 +373,58 @@ _compare_vulkan_window (GWeakRef * ref, GstVulkanWindow * window) return !equal; } -static GList * -_find_window_list_item (GstVulkanDisplay * display, GstVulkanWindow * window) +static void +prepend_window_weakref_item (GWeakRef * ref, GList ** new) { - GList *l; + GstVulkanWindow *window = g_weak_ref_get (ref); + if (window) { + *new = g_list_prepend (*new, window); + } +} - if (!window) - return NULL; +static GList * +window_weak_list_to_strong (GstVulkanDisplay * display) +{ + GList *new = NULL; + g_list_foreach (display->windows, (GFunc) prepend_window_weakref_item, &new); + return new; +} - l = g_list_find_custom (display->windows, window, - (GCompareFunc) _compare_vulkan_window); +/** + * 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; - return l; + 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); + + 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); diff --git a/gst-libs/gst/vulkan/gstvkdisplay.h b/gst-libs/gst/vulkan/gstvkdisplay.h index 2a17ebaf84..223c224a46 100644 --- a/gst-libs/gst/vulkan/gstvkdisplay.h +++ b/gst-libs/gst/vulkan/gstvkdisplay.h @@ -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