From 7b38def8e0b00abb5bdd36dcc8d030612d1d7138 Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Sun, 3 Nov 2019 12:55:13 +0100 Subject: [PATCH] structure: add gst_structure_take MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (╯°□°)╯︵ ┻━┻ --- gst/gststructure.c | 41 +++++++++++++++++++++++++++++++++++++++++ gst/gststructure.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/gst/gststructure.c b/gst/gststructure.c index fafaa65c33..4288c4a4ee 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -418,6 +418,47 @@ gst_clear_structure (GstStructure ** structure_ptr) g_clear_pointer (structure_ptr, gst_structure_free); } +/** + * gst_structure_take: + * @oldstr_ptr: (inout) (transfer full) (nullable): pointer to a place of + * a #GstStructure to take + * @newstr: (transfer full) (allow-none): a new #GstStructure + * + * Atomically modifies a pointer to point to a new object. + * The #GstStructure @oldstr_ptr is pointing to is freed and + * @newstr is taken ownership over. + * + * Either @newstr and the value pointed to by @oldstr_ptr may be %NULL. + * + * Returns: %TRUE if @newstr was different from @oldstr_ptr + * + * Since: 1.18 + */ +gboolean +gst_structure_take (GstStructure ** oldstr_ptr, GstStructure * newstr) +{ + GstStructure *oldstr; + + g_return_val_if_fail (oldstr_ptr != NULL, FALSE); + + oldstr = g_atomic_pointer_get ((gpointer *) oldstr_ptr); + + if (G_UNLIKELY (oldstr == newstr)) + return FALSE; + + while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *) + oldstr_ptr, oldstr, newstr))) { + oldstr = g_atomic_pointer_get ((gpointer *) oldstr_ptr); + if (G_UNLIKELY (oldstr == newstr)) + break; + } + + if (oldstr) + gst_structure_free (oldstr); + + return oldstr != newstr; +} + /** * gst_structure_get_name: * @structure: a #GstStructure diff --git a/gst/gststructure.h b/gst/gststructure.h index 8df9bc3bb9..a267bc8735 100644 --- a/gst/gststructure.h +++ b/gst/gststructure.h @@ -137,6 +137,9 @@ GST_API void gst_clear_structure (GstStructure **structure_ptr); #define gst_clear_structure(structure_ptr) g_clear_pointer ((structure_ptr), gst_structure_free) +GST_API +gboolean gst_structure_take (GstStructure ** oldstr_ptr, + GstStructure * newstr); GST_API const gchar * gst_structure_get_name (const GstStructure * structure);