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.
This commit is contained in:
Tim-Philipp Müller 2010-06-23 11:02:16 +01:00
parent 9c6b87510e
commit 3410d665d7
6 changed files with 85 additions and 1 deletions

View file

@ -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);

View file

@ -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 :)

View file

@ -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);

View file

@ -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:

View file

@ -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;
}

View file

@ -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);