From c3533ddec2c33ae6b0bb935c69e63dab0e9656b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Sat, 6 Dec 2025 15:48:20 +0100 Subject: [PATCH] clapper: reactable: Add timeline insert/remove functions Similar to queue alternation functions present in reactable, also add ones for timeline alternations as these are a must for non-newly created items. For consistency, remove auto thread switching logic from insert/remove functions in ClapperTimeline object. Such behavior is unexpected and I feel it could lead to potential issues such as deadlocks. --- src/lib/clapper/clapper-reactable.c | 52 ++++++++++++++++++++++ src/lib/clapper/clapper-reactable.h | 9 ++++ src/lib/clapper/clapper-timeline-private.h | 6 --- src/lib/clapper/clapper-timeline.c | 52 +++++++--------------- src/lib/clapper/clapper-utils.c | 4 +- 5 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/lib/clapper/clapper-reactable.c b/src/lib/clapper/clapper-reactable.c index 2d3d2dc8..f0d87cfe 100644 --- a/src/lib/clapper/clapper-reactable.c +++ b/src/lib/clapper/clapper-reactable.c @@ -206,3 +206,55 @@ clapper_reactable_queue_clear_sync (ClapperReactable *self) clapper_utils_queue_clear_on_main_sync (queue); }); } + +/** + * clapper_reactable_timeline_insert_sync: + * @reactable: a #ClapperReactable + * @timeline: a #ClapperTimeline + * @marker: a #ClapperMarker + * + * A convenience function that within application main thread synchronously + * inserts @marker into @timeline. + * + * Reactable enhancers should only modify timeline of an item that is already + * in queue from the application main thread, switching thread either themselves + * or using this convenience function that does so. + * + * Since: 0.10 + */ +void +clapper_reactable_timeline_insert_sync (ClapperReactable *self, + ClapperTimeline *timeline, ClapperMarker *marker) +{ + g_return_if_fail (CLAPPER_IS_REACTABLE (self)); + g_return_if_fail (CLAPPER_IS_TIMELINE (timeline)); + g_return_if_fail (CLAPPER_IS_MARKER (marker)); + + clapper_utils_timeline_insert_on_main_sync (timeline, marker); +} + +/** + * clapper_reactable_timeline_remove_sync: + * @reactable: a #ClapperReactable + * @timeline: a #ClapperTimeline + * @marker: a #ClapperMarker + * + * A convenience function that within application main thread synchronously + * removes @marker from @timeline. + * + * Reactable enhancers should only modify timeline of an item that is already + * in queue from the application main thread, switching thread either themselves + * or using this convenience function that does so. + * + * Since: 0.10 + */ +void +clapper_reactable_timeline_remove_sync (ClapperReactable *self, + ClapperTimeline *timeline, ClapperMarker *marker) +{ + g_return_if_fail (CLAPPER_IS_REACTABLE (self)); + g_return_if_fail (CLAPPER_IS_TIMELINE (timeline)); + g_return_if_fail (CLAPPER_IS_MARKER (marker)); + + clapper_utils_timeline_remove_on_main_sync (timeline, marker); +} diff --git a/src/lib/clapper/clapper-reactable.h b/src/lib/clapper/clapper-reactable.h index d5fe0791..54ab58e0 100644 --- a/src/lib/clapper/clapper-reactable.h +++ b/src/lib/clapper/clapper-reactable.h @@ -28,6 +28,9 @@ #include #include +#include +#include +#include #include G_BEGIN_DECLS @@ -237,4 +240,10 @@ void clapper_reactable_queue_remove_sync (ClapperReactable *reactable, ClapperMe CLAPPER_API void clapper_reactable_queue_clear_sync (ClapperReactable *reactable); +CLAPPER_API +void clapper_reactable_timeline_insert_sync (ClapperReactable *reactable, ClapperTimeline *timeline, ClapperMarker *marker); + +CLAPPER_API +void clapper_reactable_timeline_remove_sync (ClapperReactable *reactable, ClapperTimeline *timeline, ClapperMarker *marker); + G_END_DECLS diff --git a/src/lib/clapper/clapper-timeline-private.h b/src/lib/clapper/clapper-timeline-private.h index f10b9f97..5e8ab7c4 100644 --- a/src/lib/clapper/clapper-timeline-private.h +++ b/src/lib/clapper/clapper-timeline-private.h @@ -34,10 +34,4 @@ gboolean clapper_timeline_set_toc (ClapperTimeline *timeline, GstToc *toc, gbool G_GNUC_INTERNAL void clapper_timeline_refresh (ClapperTimeline *timeline); -G_GNUC_INTERNAL -void clapper_timeline_insert_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker); - -G_GNUC_INTERNAL -void clapper_timeline_remove_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker); - G_END_DECLS diff --git a/src/lib/clapper/clapper-timeline.c b/src/lib/clapper/clapper-timeline.c index 9fa7425e..2a83a920 100644 --- a/src/lib/clapper/clapper-timeline.c +++ b/src/lib/clapper/clapper-timeline.c @@ -188,12 +188,22 @@ _take_marker_unlocked (ClapperTimeline *self, ClapperMarker *marker) return g_sequence_iter_get_position (iter); } +/** + * clapper_timeline_insert_marker: + * @timeline: a #ClapperTimeline + * @marker: a #ClapperMarker + * + * Insert the #ClapperMarker into @timeline. + */ void -clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *marker) +clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker) { gboolean success; gint position = 0; + g_return_if_fail (CLAPPER_IS_TIMELINE (self)); + g_return_if_fail (CLAPPER_IS_MARKER (marker)); + GST_OBJECT_LOCK (self); if ((success = !g_sequence_lookup (self->markers_seq, marker, @@ -211,31 +221,22 @@ clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *m } /** - * clapper_timeline_insert_marker: + * clapper_timeline_remove_marker: * @timeline: a #ClapperTimeline * @marker: a #ClapperMarker * - * Insert the #ClapperMarker into @timeline. + * Removes #ClapperMarker from the timeline if present. */ void -clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker) -{ - g_return_if_fail (CLAPPER_IS_TIMELINE (self)); - g_return_if_fail (CLAPPER_IS_MARKER (marker)); - - if (g_main_context_is_owner (g_main_context_default ())) - clapper_timeline_insert_marker_internal (self, marker); - else - clapper_utils_timeline_insert_on_main_sync (self, marker); -} - -void -clapper_timeline_remove_marker_internal (ClapperTimeline *self, ClapperMarker *marker) +clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker) { GSequenceIter *iter; gint position = 0; gboolean success = FALSE; + g_return_if_fail (CLAPPER_IS_TIMELINE (self)); + g_return_if_fail (CLAPPER_IS_MARKER (marker)); + GST_OBJECT_LOCK (self); if ((iter = g_sequence_lookup (self->markers_seq, marker, @@ -256,25 +257,6 @@ clapper_timeline_remove_marker_internal (ClapperTimeline *self, ClapperMarker *m } } -/** - * clapper_timeline_remove_marker: - * @timeline: a #ClapperTimeline - * @marker: a #ClapperMarker - * - * Removes #ClapperMarker from the timeline if present. - */ -void -clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker) -{ - g_return_if_fail (CLAPPER_IS_TIMELINE (self)); - g_return_if_fail (CLAPPER_IS_MARKER (marker)); - - if (g_main_context_is_owner (g_main_context_default ())) - clapper_timeline_remove_marker_internal (self, marker); - else - clapper_utils_timeline_remove_on_main_sync (self, marker); -} - /** * clapper_timeline_get_marker: * @timeline: a #ClapperTimeline diff --git a/src/lib/clapper/clapper-utils.c b/src/lib/clapper/clapper-utils.c index ba5648c6..7fd55a2b 100644 --- a/src/lib/clapper/clapper-utils.c +++ b/src/lib/clapper/clapper-utils.c @@ -136,11 +136,11 @@ clapper_utils_list_alter_on_main (ClapperUtilsListAlterData *data) clapper_queue_clear (CLAPPER_QUEUE_CAST (data->list)); break; case CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT: - clapper_timeline_insert_marker_internal (CLAPPER_TIMELINE_CAST (data->list), + clapper_timeline_insert_marker (CLAPPER_TIMELINE_CAST (data->list), CLAPPER_MARKER_CAST (data->item)); break; case CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE: - clapper_timeline_remove_marker_internal (CLAPPER_TIMELINE_CAST (data->list), + clapper_timeline_remove_marker (CLAPPER_TIMELINE_CAST (data->list), CLAPPER_MARKER_CAST (data->item)); break; default: