gl/display: Add thread-safe retrieve_window

Returning a transfer none value for a value checked by a lock is not
thread safe as the reference could disappear before the caller can take
its reference.
This commit is contained in:
Matthew Waters 2019-11-02 22:58:42 +11:00 committed by GStreamer Merge Bot
parent a724f9ddfb
commit d79d742492
3 changed files with 40 additions and 10 deletions

View file

@ -636,6 +636,8 @@ gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window)
* @data: (closure): some data to pass to @compare_func * @data: (closure): some data to pass to @compare_func
* @compare_func: (scope call): a comparison function to run * @compare_func: (scope call): a comparison function to run
* *
* Deprecated for gst_gl_display_retrieve_window().
*
* Execute @compare_func over the list of windows stored by @display. The * Execute @compare_func over the list of windows stored by @display. The
* first argument to @compare_func is the #GstGLWindow being checked and the * first argument to @compare_func is the #GstGLWindow being checked and the
* second argument is @data. * second argument is @data.
@ -648,6 +650,34 @@ gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window)
GstGLWindow * GstGLWindow *
gst_gl_display_find_window (GstGLDisplay * display, gpointer data, gst_gl_display_find_window (GstGLDisplay * display, gpointer data,
GCompareFunc compare_func) GCompareFunc compare_func)
{
GstGLWindow *ret;
ret = gst_gl_display_retrieve_window (display, data, compare_func);
if (ret)
gst_object_unref (ret);
return ret;
}
/**
* gst_gl_display_retrieve_window:
* @display: a #GstGLDisplay
* @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 #GstGLWindow being checked and the
* second argument is @data.
*
* Returns: (transfer full): The first #GstGLWindow that causes a match
* from @compare_func
*
* Since: 1.18
*/
GstGLWindow *
gst_gl_display_retrieve_window (GstGLDisplay * display, gpointer data,
GCompareFunc compare_func)
{ {
GstGLWindow *ret = NULL; GstGLWindow *ret = NULL;
GList *l; GList *l;
@ -655,7 +685,10 @@ gst_gl_display_find_window (GstGLDisplay * display, gpointer data,
GST_OBJECT_LOCK (display); GST_OBJECT_LOCK (display);
l = g_list_find_custom (display->windows, data, compare_func); l = g_list_find_custom (display->windows, data, compare_func);
if (l) if (l)
ret = l->data; 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); GST_OBJECT_UNLOCK (display);
return ret; return ret;

View file

@ -148,8 +148,10 @@ GST_GL_API
GstGLWindow * gst_gl_display_create_window (GstGLDisplay * display); GstGLWindow * gst_gl_display_create_window (GstGLDisplay * display);
GST_GL_API GST_GL_API
gboolean gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window); gboolean gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window);
GST_GL_API GST_GL_API G_DEPRECATED_FOR(gst_gl_display_retrieve_window)
GstGLWindow * gst_gl_display_find_window (GstGLDisplay * display, gpointer data, GCompareFunc compare_func); GstGLWindow * gst_gl_display_find_window (GstGLDisplay * display, gpointer data, GCompareFunc compare_func);
GST_GL_API
GstGLWindow * gst_gl_display_retrieve_window (GstGLDisplay * display, gpointer data, GCompareFunc compare_func);
G_END_DECLS G_END_DECLS

View file

@ -188,20 +188,15 @@ _find_window_from_xcb_window (GstGLDisplayX11 * display_x11,
xcb_window_t window_id) xcb_window_t window_id)
{ {
GstGLDisplay *display = GST_GL_DISPLAY (display_x11); GstGLDisplay *display = GST_GL_DISPLAY (display_x11);
GstGLWindowX11 *ret = NULL; GstGLWindow *window = NULL;
GList *l;
if (!window_id) if (!window_id)
return NULL; return NULL;
GST_OBJECT_LOCK (display); window = gst_gl_display_retrieve_window (display, &window_id,
l = g_list_find_custom (display->windows, &window_id,
(GCompareFunc) _compare_xcb_window); (GCompareFunc) _compare_xcb_window);
if (l)
ret = gst_object_ref (l->data);
GST_OBJECT_UNLOCK (display);
return ret; return (GstGLWindowX11 *) window;
} }
static GstGLWindowX11 * static GstGLWindowX11 *