From 22113dc9cb019fb416bbd16022baafa44ded8180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 4 Jun 2020 12:35:11 +0300 Subject: [PATCH] gstreamer/iterator: Store filter types in a hash table Static variables in generic functions only exist once and not once per type parameter, so before we were only able to register exactly one filter type. --- gstreamer/src/iterator.rs | 47 +++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/gstreamer/src/iterator.rs b/gstreamer/src/iterator.rs index 10a1bd675..d51702dd0 100644 --- a/gstreamer/src/iterator.rs +++ b/gstreamer/src/iterator.rs @@ -358,38 +358,51 @@ unsafe extern "C" fn filter_boxed_unref(boxed: gpointer) { } unsafe extern "C" fn filter_boxed_get_type() -> glib_sys::GType { - use std::sync::Once; + use once_cell::sync::Lazy; + use std::collections::HashMap; + use std::sync::Mutex; - static mut TYPE: glib_sys::GType = gobject_sys::G_TYPE_INVALID; - static ONCE: Once = Once::new(); + static mut TYPES: Lazy>> = + Lazy::new(|| Mutex::new(HashMap::new())); - ONCE.call_once(|| { - let type_name = { + let mut types = TYPES.lock().unwrap(); + let type_name = T::static_type().name(); + + if let Some(type_) = types.get(&type_name) { + return *type_; + } + + let type_ = { + let iter_type_name = { let mut idx = 0; loop { - let type_name = CString::new(format!( - "GstRsIteratorFilterBoxed-{}-{}", - T::static_type().name(), - idx - )) - .unwrap(); - if gobject_sys::g_type_from_name(type_name.as_ptr()) == gobject_sys::G_TYPE_INVALID + let iter_type_name = + CString::new(format!("GstRsIteratorFilterBoxed-{}-{}", type_name, idx)) + .unwrap(); + if gobject_sys::g_type_from_name(iter_type_name.as_ptr()) + == gobject_sys::G_TYPE_INVALID { - break type_name; + break iter_type_name; } idx += 1; } }; - TYPE = gobject_sys::g_boxed_type_register_static( - type_name.as_ptr(), + let type_ = gobject_sys::g_boxed_type_register_static( + iter_type_name.as_ptr(), Some(filter_boxed_ref::), Some(filter_boxed_unref::), ); - }); - TYPE + assert_ne!(type_, gobject_sys::G_TYPE_INVALID); + + type_ + }; + + types.insert(type_name, type_); + + type_ } unsafe extern "C" fn find_trampoline bool>(