info: bring lazy initialization of the categories into API

This improves the usability of the framework, because it
allows to avoid calling GST_DEBUG_CATEGORY_INIT().
By avoiding calling GST_DEBUG_CATEGORY_INIT() we
get rid of the "uninitialized category" error as a type,
don't have to think where to put it, and in the end
it allows us to write less code.
At a first impression it may seem that the lazy initialization
of the category has some micro performance cost, but in fact
it can also be seen the way around: if GST_DEBUG is not set,
the category won't be initialized at all, that is a micro
performance win.
This commit is contained in:
Alexander Slobodeniuk 2024-04-12 01:24:02 +02:00
parent 0e3e688bed
commit aaa832ed4b
2 changed files with 301 additions and 1 deletions

View file

@ -10710,6 +10710,102 @@ This macro expands to nothing if debugging is disabled.</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="DEBUG_CATEGORY_DEFINE" c:identifier="GST_DEBUG_CATEGORY_DEFINE" version="1.26" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">Defines a new #GstDebugCategory, that will be initialized with the
given properties on the first logging.
It should be used together with the GST_DEBUG_CATEGORY_LAZY_INIT() macro.
Example:
|[&lt;!-- language="C" --&gt;
GST_DEBUG_CATEGORY_DEFINE (myplugin_dbg, "myplugin",
0, "nice element");
#define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
]|
NOTE: this macro defines the category as an export symbol that will be
accessible from the other object files. If the category is not used
in another object files use GST_DEBUG_CATEGORY_DEFINE_STATIC().
&gt; This macro expands to nothing if debugging is disabled.
&gt;
&gt; When naming your category, please follow the following conventions to ensure
&gt; that the pattern matching for categories works as expected. It is not
&gt; earth-shattering if you don't follow these conventions, but it would be nice
&gt; for everyone.
&gt;
&gt; If you define a category for a plugin or a feature of it, name the category
&gt; like the feature. So if you wanted to write a "filesrc" element, you would
&gt; name the category "filesrc". Use lowercase letters only.
&gt; If you define more than one category for the same element, append an
&gt; underscore and an identifier to your categories, like this: "filesrc_cache"
&gt;
&gt; If you create a library or an application using debugging categories, use a
&gt; common prefix followed by an underscore for all your categories. GStreamer
&gt; uses the GST prefix so GStreamer categories look like "GST_STATES". Be sure
&gt; to include uppercase letters.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstinfo.h"/>
<parameters>
<parameter name="cat">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the category variable name.</doc>
</parameter>
<parameter name="name">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the name of the category.</doc>
</parameter>
<parameter name="color">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the colors to use for a color representation or 0 for no color.</doc>
</parameter>
<parameter name="description">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">optional description of the category.</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="DEBUG_CATEGORY_DEFINE_STATIC" c:identifier="GST_DEBUG_CATEGORY_DEFINE_STATIC" version="1.26" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">Defines a new #GstDebugCategory, that will be initialized with the
given properties on the first logging.
It should be used together with the GST_DEBUG_CATEGORY_LAZY_INIT() macro.
Example:
|[&lt;!-- language="C" --&gt;
GST_DEBUG_CATEGORY_DEFINE_STATIC (myplugin_dbg, "myplugin",
0, "nice element");
#define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
]|
NOTE: this macro defines the category as a local static variable that won't be
accessible from the other object files. If the category is going to be used
in another code files use GST_DEBUG_CATEGORY_DEFINE().
&gt; This macro expands to nothing if debugging is disabled.
&gt;
&gt; When naming your category, please follow the following conventions to ensure
&gt; that the pattern matching for categories works as expected. It is not
&gt; earth-shattering if you don't follow these conventions, but it would be nice
&gt; for everyone.
&gt;
&gt; If you define a category for a plugin or a feature of it, name the category
&gt; like the feature. So if you wanted to write a "filesrc" element, you would
&gt; name the category "filesrc". Use lowercase letters only.
&gt; If you define more than one category for the same element, append an
&gt; underscore and an identifier to your categories, like this: "filesrc_cache"
&gt;
&gt; If you create a library or an application using debugging categories, use a
&gt; common prefix followed by an underscore for all your categories. GStreamer
&gt; uses the GST prefix so GStreamer categories look like "GST_STATES". Be sure
&gt; to include uppercase letters.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstinfo.h"/>
<parameters>
<parameter name="cat">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the category variable name.</doc>
</parameter>
<parameter name="name">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the name of the category.</doc>
</parameter>
<parameter name="color">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the colors to use for a color representation or 0 for no color.</doc>
</parameter>
<parameter name="description">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">optional description of the category.</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="DEBUG_CATEGORY_EXTERN" c:identifier="GST_DEBUG_CATEGORY_EXTERN" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">Declares a GstDebugCategory variable as extern. Use in header files.
This macro expands to nothing if debugging is disabled.</doc>
@ -10780,6 +10876,31 @@ the default threshold.
</parameter>
</parameters>
</function-macro>
<function-macro name="DEBUG_CATEGORY_LAZY_INIT" c:identifier="GST_DEBUG_CATEGORY_LAZY_INIT" version="1.26" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">This macro will return debug category @cat defined with GST_DEBUG_CATEGORY_DEFINE()
or GST_DEBUG_CATEGORY_DEFINE_STATIC().
If the category @cat haven't been initialized, it will perform the initialization
first.
It is typically used this way:
|[&lt;!-- language="C" --&gt;
GST_DEBUG_CATEGORY_DEFINE_STATIC (myplugin_dbg, "myplugin",
0, "nice element");
#define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
]|
or if the category is defined in another object file:
|[&lt;!-- language="C" --&gt;
GST_DEBUG_CATEGORY_EXTERN (myplugin_dbg);
#define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
]|
So there's no need to call GST_DEBUG_CATEGORY_INIT() for the selected
category at all: it will be initialized on the first logging.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstinfo.h"/>
<parameters>
<parameter name="cat">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">the category to use.</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="DEBUG_CATEGORY_STATIC" c:identifier="GST_DEBUG_CATEGORY_STATIC" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstinfo.h">Defines a static GstDebugCategory variable.
This macro expands to nothing if debugging is disabled.</doc>

View file

@ -614,7 +614,9 @@ G_STMT_START{ \
* Declares a GstDebugCategory variable as extern. Use in header files.
* This macro expands to nothing if debugging is disabled.
*/
#define GST_DEBUG_CATEGORY_EXTERN(cat) extern GstDebugCategory *cat
#define GST_DEBUG_CATEGORY_EXTERN(cat) \
extern GstDebugCategory *cat; \
GstDebugCategory *cat##_init (void)
/**
* GST_DEBUG_CATEGORY_STATIC:
@ -659,6 +661,180 @@ G_STMT_START{ \
cat = _gst_debug_category_new (name,color,description); \
}G_STMT_END
/**
* GST_DEBUG_CATEGORY_DEFINE:
* @cat: the category variable name.
* @name: the name of the category.
* @color: the colors to use for a color representation or 0 for no color.
* @description: optional description of the category.
*
* Defines a new #GstDebugCategory, that will be initialized with the
* given properties on the first logging.
* It should be used together with the GST_DEBUG_CATEGORY_LAZY_INIT() macro.
* Example:
* |[<!-- language="C" -->
* GST_DEBUG_CATEGORY_DEFINE (myplugin_dbg, "myplugin",
* 0, "nice element");
* #define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
* ]|
*
* NOTE: this macro defines the category as an export symbol that will be
* accessible from the other object files. If the category is not used
* in another object files use GST_DEBUG_CATEGORY_DEFINE_STATIC().
*
* > This macro expands to nothing if debugging is disabled.
* >
* > When naming your category, please follow the following conventions to ensure
* > that the pattern matching for categories works as expected. It is not
* > earth-shattering if you don't follow these conventions, but it would be nice
* > for everyone.
* >
* > If you define a category for a plugin or a feature of it, name the category
* > like the feature. So if you wanted to write a "filesrc" element, you would
* > name the category "filesrc". Use lowercase letters only.
* > If you define more than one category for the same element, append an
* > underscore and an identifier to your categories, like this: "filesrc_cache"
* >
* > If you create a library or an application using debugging categories, use a
* > common prefix followed by an underscore for all your categories. GStreamer
* > uses the GST prefix so GStreamer categories look like "GST_STATES". Be sure
* > to include uppercase letters.
*
* Since: 1.26
*/
#define GST_DEBUG_CATEGORY_DEFINE(cat,name,color,description) \
__GST_DEBUG_CATEGORY_DEFINE_MAYBE_STATIC (cat,name, color, description,)
/**
* GST_DEBUG_CATEGORY_DEFINE_STATIC:
* @cat: the category variable name.
* @name: the name of the category.
* @color: the colors to use for a color representation or 0 for no color.
* @description: optional description of the category.
*
* Defines a new #GstDebugCategory, that will be initialized with the
* given properties on the first logging.
* It should be used together with the GST_DEBUG_CATEGORY_LAZY_INIT() macro.
* Example:
* |[<!-- language="C" -->
* GST_DEBUG_CATEGORY_DEFINE_STATIC (myplugin_dbg, "myplugin",
* 0, "nice element");
* #define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
* ]|
*
* NOTE: this macro defines the category as a local static variable that won't be
* accessible from the other object files. If the category is going to be used
* in another code files use GST_DEBUG_CATEGORY_DEFINE().
*
* > This macro expands to nothing if debugging is disabled.
* >
* > When naming your category, please follow the following conventions to ensure
* > that the pattern matching for categories works as expected. It is not
* > earth-shattering if you don't follow these conventions, but it would be nice
* > for everyone.
* >
* > If you define a category for a plugin or a feature of it, name the category
* > like the feature. So if you wanted to write a "filesrc" element, you would
* > name the category "filesrc". Use lowercase letters only.
* > If you define more than one category for the same element, append an
* > underscore and an identifier to your categories, like this: "filesrc_cache"
* >
* > If you create a library or an application using debugging categories, use a
* > common prefix followed by an underscore for all your categories. GStreamer
* > uses the GST prefix so GStreamer categories look like "GST_STATES". Be sure
* > to include uppercase letters.
*
* Since: 1.26
*/
#define GST_DEBUG_CATEGORY_DEFINE_STATIC(cat,name,color,description) \
__GST_DEBUG_CATEGORY_DEFINE_MAYBE_STATIC(cat,name, color, description, static)
/**
* __GST_DEBUG_CATEGORY_DEFINE_MAYBE_STATIC: (skip)
*
* Only for private usage, part of GST_DEBUG_CATEGORY_DEFINE
*
* Since: 1.26
*/
#define __GST_DEBUG_CATEGORY_DEFINE_MAYBE_STATIC(cat,name,color,description,maybe_static) \
maybe_static GstDebugCategory *cat = NULL; \
maybe_static GstDebugCategory *cat##_init (void); \
maybe_static GstDebugCategory *cat##_init (void) \
{ \
G_STATIC_ASSERT (sizeof(gsize) == sizeof(gpointer)); \
if (g_once_init_enter ((gsize*)&cat)) { \
g_once_init_leave ((gsize*)&cat, \
(gsize)_gst_debug_category_new (name,color,description)); \
} \
\
return cat; \
}
/**
* _gst_atomic_pointer_get_relaxed:
* @atomic: pointer to the pointer-sized atomic
*
* Get current value of a pointer sized-atomic.
*
* Returns: current value of a pointer sized-atomic
*
* Since: 1.26
*/
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined (__STDC_NO_ATOMICS__)
#include <stdatomic.h>
static inline gpointer
_gst_atomic_pointer_get_relaxed (gpointer atomic)
{
_Atomic (gpointer) *tmp = (_Atomic (gpointer)*)atomic;
return atomic_load_explicit (tmp, memory_order_relaxed);
}
#elif defined(__ATOMIC_RELAXED)
#define _gst_atomic_pointer_get_relaxed(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
gpointer temp_newval; \
gpointer *temp_atomic = (gpointer *)(atomic); \
__atomic_load (temp_atomic, &temp_newval, __ATOMIC_RELAXED); \
temp_newval; \
}))
#else
/* Fallback (undesired) */
#define _gst_atomic_pointer_get_relaxed(atomic) g_atomic_pointer_get (atomic)
#endif
/**
* GST_DEBUG_CATEGORY_LAZY_INIT:
* @cat: the category to use.
*
* This macro will return debug category @cat defined with GST_DEBUG_CATEGORY_DEFINE()
* or GST_DEBUG_CATEGORY_DEFINE_STATIC().
* If the category @cat haven't been initialized, it will perform the initialization
* first.
* It is typically used this way:
* |[<!-- language="C" -->
* GST_DEBUG_CATEGORY_DEFINE_STATIC (myplugin_dbg, "myplugin",
* 0, "nice element");
* #define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
* ]|
* or if the category is defined in another object file:
* |[<!-- language="C" -->
* GST_DEBUG_CATEGORY_EXTERN (myplugin_dbg);
* #define GST_CAT_DEFAULT GST_DEBUG_CATEGORY_LAZY_INIT (myplugin_dbg)
* ]|
* So there's no need to call GST_DEBUG_CATEGORY_INIT() for the selected
* category at all: it will be initialized on the first logging.
*
* Returns: initialized debug category
*
* Since: 1.26
*/
#define GST_DEBUG_CATEGORY_LAZY_INIT(cat) \
(G_LIKELY ((cat = (GstDebugCategory *) \
_gst_atomic_pointer_get_relaxed (&cat))) ? \
cat : (cat = cat##_init ()))
/**
* GST_DEBUG_CATEGORY_GET:
* @cat: the category to initialize.
@ -1863,6 +2039,9 @@ GST_TRACE (const char *format, ...)
#define GST_DEBUG_CATEGORY(var) void _gst_debug_dummy_##var (void)
#define GST_DEBUG_CATEGORY_EXTERN(var) void _gst_debug_dummy_extern_##var (void)
#define GST_DEBUG_CATEGORY_STATIC(var) void _gst_debug_dummy_static_##var (void)
#define GST_DEBUG_CATEGORY_DEFINE(var,name,color,desc) void _gst_debug_dummy_define_##var (void)
#define GST_DEBUG_CATEGORY_DEFINE_STATIC(var,name,color,desc) void _gst_debug_dummy_define_static_##var (void)
#define GST_DEBUG_CATEGORY_LAZY_INIT(cat)
#define GST_DEBUG_CATEGORY_INIT(var,name,color,desc) G_STMT_START{ }G_STMT_END
#define GST_DEBUG_CATEGORY_GET(var,name) G_STMT_START{ }G_STMT_END