From 3410d665d74609802818ef734439b4414a6943b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 23 Jun 2010 11:02:16 +0100 Subject: [PATCH] binaryregistry: ignore the plugin cache if the filter environment has changed Make sure that we properly update the registry and the cache file whenever the filter environment changes or there's no more filter set. --- gst/gst_private.h | 2 ++ gst/gstplugin.c | 15 +++++++++++++++ gst/gstregistrybinary.c | 18 ++++++++++++++++++ gst/gstregistrybinary.h | 2 +- gst/gstregistrychunks.c | 36 ++++++++++++++++++++++++++++++++++++ gst/gstregistrychunks.h | 13 +++++++++++++ 6 files changed, 85 insertions(+), 1 deletion(-) diff --git a/gst/gst_private.h b/gst/gst_private.h index 7ca941001c..36e03efe29 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -75,6 +75,8 @@ struct _GstPluginPrivate { gboolean priv_gst_plugin_loading_have_whitelist (void); +guint32 priv_gst_plugin_loading_get_whitelist_hash (void); + gboolean priv_gst_plugin_desc_is_whitelisted (GstPluginDesc * desc, const gchar * filename); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 8a5b196857..c8215bde16 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -463,6 +463,21 @@ priv_gst_plugin_loading_have_whitelist (void) return (_plugin_loading_whitelist != NULL); } +guint32 +priv_gst_plugin_loading_get_whitelist_hash (void) +{ + guint32 hash = 0; + + if (_plugin_loading_whitelist != NULL) { + gchar **w; + + for (w = _plugin_loading_whitelist; *w != NULL; ++w) + hash = (hash << 1) ^ g_str_hash (*w); + } + + return hash; +} + /* this function could be extended to check if the plugin license matches the * applications license (would require the app to register its license somehow). * We'll wait for someone who's interested in it to code it :) diff --git a/gst/gstregistrybinary.c b/gst/gstregistrybinary.c index bef0c429f8..d680ebc165 100644 --- a/gst/gstregistrybinary.c +++ b/gst/gstregistrybinary.c @@ -377,6 +377,9 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location) } } + _priv_gst_registry_chunks_save_global_header (&to_write, registry, + priv_gst_plugin_loading_get_whitelist_hash ()); + GST_INFO ("Writing binary registry cache"); cache = gst_registry_binary_cache_init (registry, location); @@ -495,6 +498,7 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) gsize size; GError *err = NULL; gboolean res = FALSE; + guint32 filter_env_hash = 0; gint check_magic_result; #ifndef GST_DISABLE_GST_DEBUG GTimer *timer = NULL; @@ -554,6 +558,18 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) goto Error; } + if (!_priv_gst_registry_chunks_load_global_header (registry, &in, + contents + size, &filter_env_hash)) { + GST_ERROR ("Couldn't read global header chunk"); + goto Error; + } + + if (filter_env_hash != priv_gst_plugin_loading_get_whitelist_hash ()) { + GST_INFO_OBJECT (registry, "Plugin loading filter environment changed, " + "ignoring plugin cache to force update with new filter environment"); + goto done; + } + /* check if there are plugins in the file */ if (G_UNLIKELY (!(((gsize) in + sizeof (GstRegistryChunkPluginElement)) < (gsize) contents + size))) { @@ -575,6 +591,8 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location) } } +done: + #ifndef GST_DISABLE_GST_DEBUG g_timer_stop (timer); seconds = g_timer_elapsed (timer, NULL); diff --git a/gst/gstregistrybinary.h b/gst/gstregistrybinary.h index 1d9dae6244..65ed5649f9 100644 --- a/gst/gstregistrybinary.h +++ b/gst/gstregistrybinary.h @@ -55,7 +55,7 @@ G_BEGIN_DECLS * This _must_ be updated whenever the registry format changes, * we currently use the core version where this change happened. */ -#define GST_MAGIC_BINARY_VERSION_STR ("0.10.23.1") +#define GST_MAGIC_BINARY_VERSION_STR ("0.10.29.1") /* * GST_MAGIC_BINARY_VERSION_LEN: diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c index 018e59ef83..7dd3ba23eb 100644 --- a/gst/gstregistrychunks.c +++ b/gst/gstregistrychunks.c @@ -837,3 +837,39 @@ fail: GST_INFO ("Reading plugin failed after %u bytes", (guint) (end - start)); return FALSE; } + +void +_priv_gst_registry_chunks_save_global_header (GList ** list, + GstRegistry * registry, guint32 filter_env_hash) +{ + GstRegistryChunkGlobalHeader *hdr; + GstRegistryChunk *chk; + + hdr = g_slice_new (GstRegistryChunkGlobalHeader); + chk = gst_registry_chunks_make_data (hdr, + sizeof (GstRegistryChunkGlobalHeader)); + + hdr->filter_env_hash = filter_env_hash; + + *list = g_list_prepend (*list, chk); + + GST_LOG ("Saved global header (filter_env_hash=0x%08x)", filter_env_hash); +} + +gboolean +_priv_gst_registry_chunks_load_global_header (GstRegistry * registry, + gchar ** in, gchar * end, guint32 * filter_env_hash) +{ + GstRegistryChunkGlobalHeader *hdr; + + align (*in); + GST_LOG ("Reading/casting for GstRegistryChunkGlobalHeader at %p", *in); + unpack_element (*in, hdr, GstRegistryChunkGlobalHeader, end, fail); + *filter_env_hash = hdr->filter_env_hash; + return TRUE; + + /* Errors */ +fail: + GST_WARNING ("Reading global header failed"); + return FALSE; +} diff --git a/gst/gstregistrychunks.h b/gst/gstregistrychunks.h index 3c7057c110..fdbac5ec86 100644 --- a/gst/gstregistrychunks.h +++ b/gst/gstregistrychunks.h @@ -50,6 +50,11 @@ typedef struct _GstRegistryChunk gboolean align; } GstRegistryChunk; +typedef struct _GstRegistryChunkGlobalHeader +{ + guint32 filter_env_hash; +} GstRegistryChunkGlobalHeader; + /* * GstRegistryChunkPluginElement: * @@ -147,6 +152,14 @@ gboolean _priv_gst_registry_chunks_load_plugin (GstRegistry * registry, gchar ** in, gchar *end, GstPlugin **out_plugin); +void +_priv_gst_registry_chunks_save_global_header (GList ** list, + GstRegistry * registry, guint32 filter_env_hash); + +gboolean +_priv_gst_registry_chunks_load_global_header (GstRegistry * registry, + gchar ** in, gchar *end, guint32 * filter_env_hash); + void _priv_gst_registry_chunk_free (GstRegistryChunk *chunk);