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
* @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
* first argument to @compare_func is the #GstGLWindow being checked and the
* second argument is @data.
@ -648,6 +650,34 @@ gst_gl_display_remove_window (GstGLDisplay * display, GstGLWindow * window)
GstGLWindow *
gst_gl_display_find_window (GstGLDisplay * display, gpointer data,
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;
GList *l;
@ -655,7 +685,10 @@ gst_gl_display_find_window (GstGLDisplay * display, gpointer data,
GST_OBJECT_LOCK (display);
l = g_list_find_custom (display->windows, data, compare_func);
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);
return ret;

View file

@ -148,8 +148,10 @@ GST_GL_API
GstGLWindow * gst_gl_display_create_window (GstGLDisplay * display);
GST_GL_API
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);
GST_GL_API
GstGLWindow * gst_gl_display_retrieve_window (GstGLDisplay * display, gpointer data, GCompareFunc compare_func);
G_END_DECLS

View file

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