vulkan/display: implement thread-safe find_window()

This commit is contained in:
Matthew Waters 2020-02-17 15:05:49 +11:00 committed by GStreamer Merge Bot
parent 0ea427823e
commit af19fa94f4
2 changed files with 52 additions and 10 deletions

View file

@ -373,18 +373,58 @@ _compare_vulkan_window (GWeakRef * ref, GstVulkanWindow * window)
return !equal; return !equal;
} }
static GList * static void
_find_window_list_item (GstVulkanDisplay * display, GstVulkanWindow * window) 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) static GList *
return NULL; 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; GList *l;
GST_OBJECT_LOCK (display); 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) { if (l) {
GWeakRef *ref = l->data; GWeakRef *ref = l->data;
display->windows = g_list_delete_link (display->windows, l); display->windows = g_list_delete_link (display->windows, l);

View file

@ -131,7 +131,8 @@ gboolean gst_vulkan_display_run_context_query (GstElement
/* GstVulkanWindow usage only */ /* GstVulkanWindow usage only */
GST_VULKAN_API GST_VULKAN_API
gboolean gst_vulkan_display_remove_window (GstVulkanDisplay * display, GstVulkanWindow * window); 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 G_END_DECLS