gst/gstregistrybinary.*: Implement no-mmap alternative for registry reading. Do code cleanups.

Original commit message from CVS:
* gst/gstregistrybinary.c: (gst_registry_binary_write_cache),
(gst_registry_binary_load_pad_template),
(gst_registry_binary_load_plugin),
(gst_registry_binary_read_cache):
* gst/gstregistrybinary.h:
Implement no-mmap alternative for registry reading. Do code cleanups.
Add more comments about avoiding strdups for all text data. Comments
welcome.
This commit is contained in:
Stefan Kost 2007-04-26 07:32:08 +00:00
parent 96438b7b4f
commit 14999bf0f5
3 changed files with 76 additions and 35 deletions

View file

@ -1,3 +1,14 @@
2007-04-26 Stefan Kost <ensonic@users.sf.net>
* gst/gstregistrybinary.c: (gst_registry_binary_write_cache),
(gst_registry_binary_load_pad_template),
(gst_registry_binary_load_plugin),
(gst_registry_binary_read_cache):
* gst/gstregistrybinary.h:
Implement no-mmap alternative for registry reading. Do code cleanups.
Add more comments about avoiding strdups for all text data. Comments
welcome.
2007-04-25 Stefan Kost <ensonic@users.sf.net> 2007-04-25 Stefan Kost <ensonic@users.sf.net>
* gst/gstregistrybinary.h (GstBinaryPluginElement, * gst/gstregistrybinary.h (GstBinaryPluginElement,

View file

@ -24,9 +24,14 @@
/* FIXME: /* FIXME:
* - Add random key to libgstreamer during build and only accept registry, * - Add random key to libgstreamer during build and only accept registry,
* if key matches (or is the version check enough) * if key matches (or is the version check enough)
* - handle cases where we can't mmap
* - keep registry binary blob and reference strings * - keep registry binary blob and reference strings
* (need const flags in GstPlugin, etc.) * - don't free/unmmap contents when leaving gst_registry_binary_read_cache()
* - free at gst_deinit() / _priv_gst_registry_cleanup() ?
* - GstPlugin:
* - GST_PLUGIN_FLAG_CONST
* -GstPluginFeature, GstIndexFactory, GstElementFactory
* - needs Flags (GST_PLUGIN_FEATURE_FLAG_CONST)
* - can we turn loaded into flag?
* - why do we collect a list of binary chunks and not write immediately * - why do we collect a list of binary chunks and not write immediately
* - because we need to process subchunks, before we can set e.g. nr_of_items * - because we need to process subchunks, before we can set e.g. nr_of_items
* in parent chunk * in parent chunk
@ -58,7 +63,7 @@
#include <gst/gstregistrybinary.h> #include <gst/gstregistrybinary.h>
#include <glib/gstdio.h> /* for g_stat() */ #include <glib/gstdio.h> /* for g_stat(), g_mapped_file(), ... */
#define GST_CAT_DEFAULT GST_CAT_REGISTRY #define GST_CAT_DEFAULT GST_CAT_REGISTRY
@ -81,6 +86,7 @@
# define align32(_ptr) do {} while(0) # define align32(_ptr) do {} while(0)
#endif #endif
/* Registry saving */ /* Registry saving */
/* /*
@ -117,6 +123,7 @@ gst_registry_binary_write (GstRegistry * registry, const void *mem,
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_initialize_magic: * gst_registry_binary_initialize_magic:
* *
@ -135,6 +142,7 @@ gst_registry_binary_initialize_magic (GstBinaryRegistryMagic * m)
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_save_string: * gst_registry_binary_save_string:
* *
@ -156,6 +164,7 @@ gst_registry_binary_save_string (GList ** list, gchar * str)
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_save_data: * gst_registry_binary_save_data:
* *
@ -176,6 +185,7 @@ gst_registry_binary_make_data (gpointer data, gulong size)
return chunk; return chunk;
} }
/* /*
* gst_registry_binary_save_pad_template: * gst_registry_binary_save_pad_template:
* *
@ -206,6 +216,7 @@ gst_registry_binary_save_pad_template (GList ** list,
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_save_feature: * gst_registry_binary_save_feature:
* *
@ -343,6 +354,7 @@ fail:
return FALSE; return FALSE;
} }
/* /*
* gst_registry_binary_save_plugin: * gst_registry_binary_save_plugin:
* *
@ -405,6 +417,7 @@ fail:
return FALSE; return FALSE;
} }
/** /**
* gst_registry_binary_write_cache: * gst_registry_binary_write_cache:
* *
@ -414,7 +427,7 @@ gboolean
gst_registry_binary_write_cache (GstRegistry * registry, const char *location) gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
{ {
GList *walk; GList *walk;
char *tmp_location; gchar *tmp_location;
GstBinaryRegistryMagic *magic; GstBinaryRegistryMagic *magic;
GstBinaryChunk *magic_chunk; GstBinaryChunk *magic_chunk;
GList *to_write = NULL; GList *to_write = NULL;
@ -426,7 +439,7 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
tmp_location = g_strconcat (location, ".tmpXXXXXX", NULL); tmp_location = g_strconcat (location, ".tmpXXXXXX", NULL);
registry->cache_file = g_mkstemp (tmp_location); registry->cache_file = g_mkstemp (tmp_location);
if (registry->cache_file == -1) { if (registry->cache_file == -1) {
char *dir; gchar *dir;
/* oops, I bet the directory doesn't exist */ /* oops, I bet the directory doesn't exist */
dir = g_path_get_dirname (location); dir = g_path_get_dirname (location);
@ -522,6 +535,7 @@ fail:
return FALSE; return FALSE;
} }
/* Registry loading */ /* Registry loading */
/* /*
@ -562,6 +576,7 @@ gst_registry_binary_check_magic (gchar ** in)
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_load_pad_template: * gst_registry_binary_load_pad_template:
* *
@ -579,7 +594,6 @@ gst_registry_binary_load_pad_template (GstElementFactory * factory, gchar ** in)
GST_DEBUG ("Reading/casting for GstBinaryPadTemplate at address %p", *in); GST_DEBUG ("Reading/casting for GstBinaryPadTemplate at address %p", *in);
unpack_element (*in, pt, GstBinaryPadTemplate); unpack_element (*in, pt, GstBinaryPadTemplate);
template = g_new0 (GstStaticPadTemplate, 1); template = g_new0 (GstStaticPadTemplate, 1);
template->presence = pt->presence; template->presence = pt->presence;
template->direction = pt->direction; template->direction = pt->direction;
@ -594,6 +608,7 @@ gst_registry_binary_load_pad_template (GstElementFactory * factory, gchar ** in)
return TRUE; return TRUE;
} }
/* /*
* gst_registry_binary_load_feature: * gst_registry_binary_load_feature:
* *
@ -741,6 +756,7 @@ fail:
return FALSE; return FALSE;
} }
/* /*
* gst_registry_binary_load_plugin: * gst_registry_binary_load_plugin:
* *
@ -774,6 +790,7 @@ gst_registry_binary_load_plugin (GstRegistry * registry, gchar ** in)
plugin = g_object_new (GST_TYPE_PLUGIN, NULL); plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
/* TODO: also set GST_PLUGIN_FLAG_CONST */
plugin->flags |= GST_PLUGIN_FLAG_CACHED; plugin->flags |= GST_PLUGIN_FLAG_CACHED;
plugin->file_mtime = pe->file_mtime; plugin->file_mtime = pe->file_mtime;
plugin->file_size = pe->file_size; plugin->file_size = pe->file_size;
@ -829,6 +846,7 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
gdouble seconds; gdouble seconds;
gsize size; gsize size;
GError *err = NULL; GError *err = NULL;
gboolean res = FALSE;
/* make sure these types exist */ /* make sure these types exist */
GST_TYPE_ELEMENT_FACTORY; GST_TYPE_ELEMENT_FACTORY;
@ -841,30 +859,35 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
mapped = g_mapped_file_new (location, FALSE, &err); mapped = g_mapped_file_new (location, FALSE, &err);
if (err != NULL) { if (err != NULL) {
GST_INFO ("Unable to mmap file: %s", err->message); GST_INFO ("Unable to mmap file %s : %s", location, err->message);
g_error_free (err); g_error_free (err);
return FALSE; err = NULL;
}
if ((contents = g_mapped_file_get_contents (mapped)) == NULL) { g_file_get_contents (location, &contents, &size, &err);
GST_ERROR ("Can't load file %s : %s", location, g_strerror (errno)); if (err != NULL) {
g_mapped_file_free (mapped); GST_INFO ("Unable to read file %s : %s", location, err->message);
return FALSE; g_error_free (err);
return FALSE;
}
} else {
if ((contents = g_mapped_file_get_contents (mapped)) == NULL) {
GST_ERROR ("Can't load file %s : %s", location, g_strerror (errno));
goto Error;
}
/* check length for header */
size = g_mapped_file_get_length (mapped);
} }
/* in is a cursor pointer, we initialize it with the begin of registry and is updated on each read */ /* in is a cursor pointer, we initialize it with the begin of registry and is updated on each read */
in = contents; in = contents;
GST_DEBUG ("File mapped at address %p", in); GST_DEBUG ("File data at address %p", in);
/* check length for header */
size = g_mapped_file_get_length (mapped);
if (size < sizeof (GstBinaryRegistryMagic)) { if (size < sizeof (GstBinaryRegistryMagic)) {
GST_INFO ("No or broken registry header"); GST_ERROR ("No or broken registry header");
return FALSE; goto Error;
} }
/* check if header is valid */ /* check if header is valid */
if (!gst_registry_binary_check_magic (&in)) { if (!gst_registry_binary_check_magic (&in)) {
GST_ERROR ("Binary registry type not recognized (invalid magic)"); GST_ERROR ("Binary registry type not recognized (invalid magic)");
g_mapped_file_free (mapped); goto Error;
return FALSE;
} }
/* check if there are plugins in the file */ /* check if there are plugins in the file */
@ -872,18 +895,18 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
if (!(((size_t) in + sizeof (GstBinaryPluginElement)) < if (!(((size_t) in + sizeof (GstBinaryPluginElement)) <
(size_t) contents + size)) { (size_t) contents + size)) {
GST_INFO ("No binary plugins structure to read"); GST_INFO ("No binary plugins structure to read");
return TRUE; /* empty file, this is not an error */ /* empty file, this is not an error */
} } else {
for (;
for (; ((size_t) in + sizeof (GstBinaryPluginElement)) <
((size_t) in + sizeof (GstBinaryPluginElement)) < (size_t) contents + size;) {
(size_t) contents + size;) { GST_INFO ("reading binary registry %" G_GSIZE_FORMAT "(%x)/%"
GST_INFO ("reading binary registry %" G_GSIZE_FORMAT "(%x)/%" G_GSIZE_FORMAT, (size_t) in - (size_t) contents,
G_GSIZE_FORMAT, (size_t) in - (size_t) contents, (guint) ((size_t) in - (size_t) contents), size);
(guint) ((size_t) in - (size_t) contents), size); if (!gst_registry_binary_load_plugin (registry, &in)) {
if (!gst_registry_binary_load_plugin (registry, &in)) { GST_ERROR ("Problem while reading binary registry");
GST_ERROR ("Problem while reading binary registry"); goto Error;
return FALSE; }
} }
} }
@ -893,6 +916,14 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
GST_INFO ("loaded %s in %lf seconds", location, seconds); GST_INFO ("loaded %s in %lf seconds", location, seconds);
g_mapped_file_free (mapped); res = TRUE;
return TRUE; /* TODO: once we re-use the pointers to registry contents return here */
Error:
if (mapped) {
g_mapped_file_free (mapped);
} else {
g_free (contents);
}
return res;
} }

View file

@ -25,7 +25,6 @@
** ==================== ** ====================
** - Use a compressed registry, but would induce performance loss ** - Use a compressed registry, but would induce performance loss
** - Encrypt the registry, for security purpose, but would also reduce performances ** - Encrypt the registry, for security purpose, but would also reduce performances
** - Also have a non-mmap based cache reading (work with file descriptors)
*/ */
#ifndef __GST_REGISTRYBINARY_H__ #ifndef __GST_REGISTRYBINARY_H__