binaryregistry: ignore the plugin cache if the filter environment has changed
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Wed, 23 Jun 2010 10:02:16 +0000 (11:02 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Wed, 23 Jun 2010 16:56:51 +0000 (17:56 +0100)
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
gst/gstplugin.c
gst/gstregistrybinary.c
gst/gstregistrybinary.h
gst/gstregistrychunks.c
gst/gstregistrychunks.h

index 7ca9410..36e03ef 100644 (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);
 
index 8a5b196..c8215bd 100644 (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 :)
index bef0c42..d680ebc 100644 (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);
index 1d9dae6..65ed564 100644 (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:
index 018e59e..7dd3ba2 100644 (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;
+}
index 3c7057c..fdbac5e 100644 (file)
@@ -50,6 +50,11 @@ typedef struct _GstRegistryChunk
   gboolean align;
 } GstRegistryChunk;
 
+typedef struct _GstRegistryChunkGlobalHeader
+{
+  guint32  filter_env_hash;
+} GstRegistryChunkGlobalHeader;
+
 /*
  * GstRegistryChunkPluginElement:
  *
@@ -148,6 +153,14 @@ _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);
 
 G_END_DECLS