gst: Add gst_deinit_register_notify() API

Add an API so that user can install a callback function to be
called when gst_deinit() is executed, then performs library specific
teardown operations such as clearing resources or reporting live
objects.
This commit is contained in:
Seungha Yang 2024-03-16 00:07:49 +09:00
parent 4790a44d10
commit b5a7d0ae48
4 changed files with 120 additions and 0 deletions

View file

@ -172,6 +172,23 @@ static gboolean parse_goption_arg (const gchar * s_opt,
GSList *_priv_gst_preload_plugins = NULL;
/* deinit callbacks */
static GList *_gst_deinit_notifies = NULL;
typedef struct _GstDeinitNotify
{
GstDeinitNotifyFunc func;
gpointer user_data;
} GstDeinitNotify;
static void
gst_deinit_notify_free (GstDeinitNotify * cb)
{
if (cb->func)
cb->func (cb->user_data);
g_free (cb);
}
enum
{
ARG_VERSION = 1,
@ -1092,6 +1109,10 @@ gst_deinit (void)
}
GST_INFO ("deinitializing GStreamer");
g_list_free_full (_gst_deinit_notifies,
(GDestroyNotify) gst_deinit_notify_free);
g_thread_pool_set_max_unused_threads (0);
bin_class = (GstBinClass *) g_type_class_peek (gst_bin_get_type ());
if (bin_class && bin_class->pool != NULL) {
@ -1326,3 +1347,40 @@ gst_segtrap_set_enabled (gboolean enabled)
{
_gst_disable_segtrap = !enabled;
}
/**
* gst_deinit_register_notify:
* @func: (scope async): a #GstDeinitNotifyFunc
* @user_data: (nullable): private user data
*
* Registers a callback notified when gst_deinit() is called.
* This could be useful for a GStreamer library where the library holds
* persistent resources but prefers the resources to be released
* when gst_deinit() is called, so that any expected resource leaks
* (either GStreamer object or native handle/memory) can be addressed.
*
* Applications or GStreamer components can register callbacks
* before GStreamer is initialized, but installing notify after gst_deinit()
* is not allowed.
*
* Since: 1.26
*/
void
gst_deinit_register_notify (GstDeinitNotifyFunc func, gpointer user_data)
{
GstDeinitNotify *cb;
g_rec_mutex_lock (&init_lock);
if (gst_deinitialized) {
g_warning ("GStreamer was deinitialized already.");
g_rec_mutex_unlock (&init_lock);
return;
}
cb = g_new0 (GstDeinitNotify, 1);
cb->func = func;
cb->user_data = user_data;
_gst_deinit_notifies = g_list_prepend (_gst_deinit_notifies, cb);
g_rec_mutex_unlock (&init_lock);
}

View file

@ -144,6 +144,18 @@ gboolean gst_update_registry (void);
GST_API
const gchar * gst_get_main_executable_path (void);
/**
* GstDeinitNotifyFunc:
* @user_data: User data registered along with this function via gst_deinit_register_notify()
*
* Since: 1.26
*/
typedef void (*GstDeinitNotifyFunc) (gpointer user_data);
GST_API
void gst_deinit_register_notify (GstDeinitNotifyFunc func,
gpointer user_data);
G_END_DECLS
#endif /* __GST_H__ */

View file

@ -0,0 +1,49 @@
/* GStreamer
* Copyright (C) 2024 Seungha Yang <seungha@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
static void
deinit_cb (guint * cb_count)
{
*cb_count += 1;
}
int
main (int argc, char **argv)
{
guint cb_count = 0;
/* Installing callback before gst_init() is allowed */
gst_deinit_register_notify ((GstDeinitNotifyFunc) deinit_cb, &cb_count);
gst_init (NULL, NULL);
/* Install callback again */
gst_deinit_register_notify ((GstDeinitNotifyFunc) deinit_cb, &cb_count);
gst_deinit ();
g_assert (cb_count == 2);
return 0;
}

View file

@ -16,6 +16,7 @@ core_tests = [
[ 'gst/gstcapsfeatures.c' ],
[ 'gst/gstdatetime.c' ],
[ 'gst/gstdeinit.c' ],
[ 'gst/gstdeinit2.c' ],
[ 'gst/gstdevice.c' ],
[ 'gst/gstelement.c', not gst_registry or not gst_parse],
[ 'gst/gstelementfactory.c', not gst_registry ],