rebuild registry only for newer plugins. fixes #145520

Original commit message from CVS:
rebuild registry only for newer plugins.  fixes #145520
This commit is contained in:
Thomas Vander Stichele 2004-07-06 17:55:25 +00:00
parent 2754a4bb4b
commit c0f5312554
4 changed files with 186 additions and 114 deletions

View file

@ -1,3 +1,13 @@
2004-07-06 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/gstplugin.c: (gst_plugin_check_file), (gst_plugin_load_file):
* gst/gstplugin.h:
* gst/registries/gstxmlregistry.c:
(plugin_times_older_than_recurse), (plugin_times_older_than),
(gst_xml_registry_parse_padtemplate):
only rebuild registry when actual plugins have a newer time than
the registry. Fixes #145520
2004-07-06 Thomas Vander Stichele <thomas at apestaart dot org> 2004-07-06 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/manual/manual.xml: * docs/manual/manual.xml:

View file

@ -296,6 +296,62 @@ _gst_plugin_fault_handler_setup (void)
static void _gst_plugin_fault_handler_setup (); static void _gst_plugin_fault_handler_setup ();
/**
* gst_plugin_check_file:
* @filename: the plugin filename to check for pluginness
* @error: pointer to a NULL-valued GError
*
* Checks if the given path represents a GStreamer plugin.
*
* Returns: TRUE if the given path is a GStreamer plugin.
*/
gboolean
gst_plugin_check_file (const gchar * filename, GError ** error)
{
GModule *module;
struct stat file_status;
g_return_val_if_fail (filename != NULL, FALSE);
if (g_module_supported () == FALSE) {
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported");
return FALSE;
}
if (stat (filename, &file_status)) {
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Problem opening file %s\n", filename);
return FALSE;
}
module = g_module_open (filename, G_MODULE_BIND_LAZY);
if (module == NULL) {
GST_DEBUG ("Error loading plugin %s, reason: %s\n", filename,
g_module_error ());
g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE,
"Error loading plugin %s, reason: %s\n", filename, g_module_error ());
return FALSE;
}
gpointer ptr;
if (!g_module_symbol (module, "gst_plugin_desc", &ptr)) {
GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename);
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE,
"Could not find plugin entry point in \"%s\"", filename);
g_module_close (module);
return FALSE;
}
/* it's a plugin */
g_module_close (module);
return TRUE;
}
/** /**
* gst_plugin_load_file: * gst_plugin_load_file:
* @filename: the plugin filename to load * @filename: the plugin filename to load
@ -311,34 +367,25 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
GstPlugin *plugin; GstPlugin *plugin;
GModule *module; GModule *module;
GstPluginDesc *desc; GstPluginDesc *desc;
struct stat file_status;
gboolean free_plugin; gboolean free_plugin;
gpointer ptr;
g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (filename != NULL, NULL);
GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"",
filename); filename);
if (g_module_supported () == FALSE) { if (!gst_plugin_check_file (filename, error))
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported");
return NULL; return NULL;
}
if (stat (filename, &file_status)) {
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, "Problem opening file %s\n", filename);
return NULL;
}
module = g_module_open (filename, G_MODULE_BIND_LAZY); module = g_module_open (filename, G_MODULE_BIND_LAZY);
if (module != NULL) { if (module == NULL)
gpointer ptr; goto load_error;
if (!g_module_symbol (module, "gst_plugin_desc", &ptr))
goto load_error;
if (g_module_symbol (module, "gst_plugin_desc", &ptr)) {
desc = (GstPluginDesc *) ptr; desc = (GstPluginDesc *) ptr;
plugin = gst_registry_pool_find_plugin (desc->name); plugin = gst_registry_pool_find_plugin (desc->name);
@ -346,8 +393,7 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
free_plugin = TRUE; free_plugin = TRUE;
plugin = g_new0 (GstPlugin, 1); plugin = g_new0 (GstPlugin, 1);
plugin->filename = g_strdup (filename); plugin->filename = g_strdup (filename);
GST_DEBUG ("created new GstPlugin %p for file \"%s\"", plugin, GST_DEBUG ("created new GstPlugin %p for file \"%s\"", plugin, filename);
filename);
} else { } else {
free_plugin = FALSE; free_plugin = FALSE;
if (gst_plugin_is_loaded (plugin)) { if (gst_plugin_is_loaded (plugin)) {
@ -394,8 +440,7 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
} else { } else {
/* remove signal handler */ /* remove signal handler */
_gst_plugin_fault_handler_restore (); _gst_plugin_fault_handler_restore ();
GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
filename);
/* plugin == NULL */ /* plugin == NULL */
g_set_error (error, g_set_error (error,
GST_PLUGIN_ERROR, GST_PLUGIN_ERROR,
@ -405,21 +450,11 @@ gst_plugin_load_file (const gchar * filename, GError ** error)
g_free (plugin); g_free (plugin);
return NULL; return NULL;
} }
} else { load_error:
GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename);
g_set_error (error, g_set_error (error,
GST_PLUGIN_ERROR, GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_MODULE, GST_PLUGIN_ERROR_MODULE, "generic load error for \"%s\"", filename);
"Could not find plugin entry point in \"%s\"", filename);
}
return NULL; return NULL;
} else {
GST_DEBUG ("Error loading plugin %s, reason: %s\n", filename,
g_module_error ());
g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE,
"Error loading plugin %s, reason: %s\n", filename, g_module_error ());
return NULL;
}
} }
static void static void

View file

@ -149,6 +149,7 @@ gboolean gst_plugin_name_filter (GstPlugin *plugin, const gchar *name);
GList* gst_plugin_get_feature_list (GstPlugin *plugin); GList* gst_plugin_get_feature_list (GstPlugin *plugin);
GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type); GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type);
gboolean gst_plugin_check_file (const gchar *filename, GError** error);
GstPlugin * gst_plugin_load_file (const gchar *filename, GError** error); GstPlugin * gst_plugin_load_file (const gchar *filename, GError** error);
gboolean gst_plugin_unload_plugin (GstPlugin *plugin); gboolean gst_plugin_unload_plugin (GstPlugin *plugin);

View file

@ -299,6 +299,7 @@ gst_xml_registry_get_property (GObject * object, guint prop_id,
* mtime is updated through an actual write (data) * mtime is updated through an actual write (data)
* ctime is updated through changing inode information * ctime is updated through changing inode information
* so this function returns the last time *anything* changed to this path * so this function returns the last time *anything* changed to this path
* it also sets the given boolean to TRUE if the given path is a directory
*/ */
static time_t static time_t
get_time (const char *path, gboolean * is_dir) get_time (const char *path, gboolean * is_dir)
@ -430,38 +431,43 @@ finished:
g_free (text); g_free (text);
} }
/* return TRUE iff regtime is more recent than the times of all the .so files
* in the plugin dirs; ie return TRUE if this path does not need to trigger
* a rebuild of registry
*
* - if it's a directory, recurse on subdirs
* - if it's a file
* - if entry is not newer, return TRUE.
* - if it's newer
* - and it's a plugin, return FALSE
* - otherwise return TRUE
*/
static gboolean static gboolean
plugin_times_older_than_recurse (gchar * path, time_t regtime) plugin_times_older_than_recurse (gchar * path, time_t regtime)
{ {
DIR *dir; DIR *dir;
struct dirent *dirent; struct dirent *dirent;
gboolean is_dir; gboolean is_dir;
gchar *pluginname; gchar *new_path;
time_t pathtime = get_time (path, &is_dir); time_t pathtime = get_time (path, &is_dir);
if (pathtime > regtime) { if (is_dir) {
GST_CAT_INFO (GST_CAT_PLUGIN_LOADING,
"time for %s was %ld; more recent than registry time of %ld\n",
path, (long) pathtime, (long) regtime);
return FALSE;
}
if (!is_dir)
return TRUE;
dir = opendir (path); dir = opendir (path);
if (dir) { if (dir) {
while ((dirent = readdir (dir))) { while ((dirent = readdir (dir))) {
/* don't want to recurse in place or backwards */ /* don't want to recurse in place or backwards */
if (strcmp (dirent->d_name, ".") && strcmp (dirent->d_name, "..")) { if (strcmp (dirent->d_name, ".") && strcmp (dirent->d_name, "..")) {
pluginname = g_strjoin ("/", path, dirent->d_name, NULL); new_path = g_build_filename (path, dirent->d_name, NULL);
if (!plugin_times_older_than_recurse (pluginname, regtime)) { if (!plugin_times_older_than_recurse (new_path, regtime)) {
g_free (pluginname); GST_CAT_INFO (GST_CAT_PLUGIN_LOADING,
"path %s is more recent than registry time of %ld",
new_path, (long) regtime);
g_free (new_path);
closedir (dir); closedir (dir);
return FALSE; return FALSE;
} }
g_free (pluginname); g_free (new_path);
} }
} }
closedir (dir); closedir (dir);
@ -469,13 +475,31 @@ plugin_times_older_than_recurse (gchar * path, time_t regtime)
return TRUE; return TRUE;
} }
/* it's a file */
if (pathtime <= regtime) {
return TRUE;
}
/* it's a file, and it's more recent */
if (g_str_has_suffix (path, ".so") || g_str_has_suffix (path, ".dll")) {
if (!gst_plugin_check_file (path, NULL))
return TRUE;
/* it's a newer GStreamer plugin */
GST_CAT_INFO (GST_CAT_PLUGIN_LOADING,
"%s looks like a plugin and is more recent than registry time of %ld",
path, (long) regtime);
return FALSE;
}
return TRUE;
}
/* return TRUE iff regtime is more recent than the times of all the .so files
* in the plugin dirs; ie return TRUE if registry is up to date.
*/
static gboolean static gboolean
plugin_times_older_than (GList * paths, time_t regtime) plugin_times_older_than (GList * paths, time_t regtime)
{ {
/* return true iff regtime is more recent than the times of all the files
* in the plugin dirs.
*/
while (paths) { while (paths) {
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, GST_CAT_LOG (GST_CAT_PLUGIN_LOADING,
"comparing plugin times from %s with %ld", "comparing plugin times from %s with %ld",
@ -484,6 +508,8 @@ plugin_times_older_than (GList * paths, time_t regtime)
return FALSE; return FALSE;
paths = g_list_next (paths); paths = g_list_next (paths);
} }
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING,
"everything's fine, no registry rebuild needed.");
return TRUE; return TRUE;
} }
@ -880,7 +906,7 @@ gst_xml_registry_parse_padtemplate (GMarkupParseContext * context,
g_assert (registry->caps == NULL); g_assert (registry->caps == NULL);
registry->caps = gst_caps_from_string (s); registry->caps = gst_caps_from_string (s);
if (registry->caps == NULL) { if (registry->caps == NULL) {
g_critical ("Could not parse caps: length %d, content: %*s\n", g_critical ("Could not parse caps: length %d, content: %*s",
(int) text_len, (int) text_len, text); (int) text_len, (int) text_len, text);
} }
g_free (s); g_free (s);