mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +00:00
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:
parent
96438b7b4f
commit
14999bf0f5
3 changed files with 76 additions and 35 deletions
11
ChangeLog
11
ChangeLog
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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__
|
||||||
|
|
Loading…
Reference in a new issue