From ad88770782310c09ff90fd377844e569b60cbb12 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 20 May 2002 23:11:10 +0000 Subject: [PATCH] add gerror to gstplugin.c -- not fully propagated to periphery apis fix recursive dir creation in the xml registry co... Original commit message from CVS: * add gerror to gstplugin.c -- not fully propagated to periphery apis * fix recursive dir creation in the xml registry * comment identity props * fix dependency resolution in lib loading --- gst/elements/gstidentity.c | 4 +- gst/gstplugin.c | 39 ++++++++++-- gst/gstplugin.h | 11 +++- gst/registries/gstxmlregistry.c | 109 ++++++++++++++++++++++++-------- plugins/elements/gstidentity.c | 4 +- 5 files changed, 128 insertions(+), 39 deletions(-) diff --git a/gst/elements/gstidentity.c b/gst/elements/gstidentity.c index a309ba06f3..24426faf3f 100644 --- a/gst/elements/gstidentity.c +++ b/gst/elements/gstidentity.c @@ -97,10 +97,10 @@ gst_identity_class_init (GstIdentityClass *klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop_based", "loop_based", "loop_based", + g_param_spec_boolean ("loop-based", "Loop-based", "Set to TRUE to use loop-based rather than chain-based scheduling", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME, - g_param_spec_uint ("sleep_time", "sleep_time", "sleep_time", + g_param_spec_uint ("sleep-time", "Sleep time", "Microseconds to sleep between processing", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE, g_param_spec_uint ("duplicate", "Duplicate Buffers", "Push the buffers N times", diff --git a/gst/gstplugin.c b/gst/gstplugin.c index addbaca36b..d73b6bf0d0 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -38,6 +38,15 @@ GList *_gst_plugin_static = NULL; static void gst_plugin_register_statics (GModule *module); static GstPlugin* gst_plugin_register_func (GstPluginDesc *desc, GstPlugin *plugin, GModule *module); +GQuark +gst_plugin_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("gst_plugin_error"); + return quark; +} + void _gst_plugin_initialize (void) { @@ -119,13 +128,14 @@ gst_plugin_new (const gchar *filename) /** * gst_plugin_load_plugin: * @plugin: The plugin to load + * @error: Pointer to a NULL-valued GError. * * Load the given plugin. * - * Returns: whether or not the plugin loaded + * Returns: whether or not the plugin loaded. Sets @error as appropriate. */ gboolean -gst_plugin_load_plugin (GstPlugin *plugin) +gst_plugin_load_plugin (GstPlugin *plugin, GError **error) { GModule *module; GstPluginDesc *desc; @@ -142,12 +152,19 @@ gst_plugin_load_plugin (GstPlugin *plugin) GST_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"", filename); if (g_module_supported () == FALSE) { - g_warning ("gstplugin: wow, you built this on a platform without dynamic loading???\n"); + g_set_error (error, + GST_PLUGIN_ERROR, + GST_PLUGIN_ERROR_MODULE, + "Dynamic loading not supported"); return FALSE; } if (stat (filename, &file_status)) { - g_warning ("problem opening file %s (plugin %s)\n", filename, plugin->name); + g_set_error (error, + GST_PLUGIN_ERROR, + GST_PLUGIN_ERROR_MODULE, + "Problem opening file %s (plugin %s)\n", + filename, plugin->name); return FALSE; } @@ -167,12 +184,20 @@ gst_plugin_load_plugin (GstPlugin *plugin) } } else { - GST_DEBUG (GST_CAT_PLUGIN_LOADING, "could not find plugin_desc in \"%s\"", filename); + g_set_error (error, + GST_PLUGIN_ERROR, + GST_PLUGIN_ERROR_MODULE, + "Could not find plugin_desc in \"%s\"", + filename); } return FALSE; } else { - GST_INFO (GST_CAT_PLUGIN_LOADING, "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; @@ -384,7 +409,7 @@ gst_plugin_load (const gchar *name) plugin = gst_registry_pool_find_plugin (name); if (plugin) - return gst_plugin_load_plugin (plugin); + return gst_plugin_load_plugin (plugin, NULL); return FALSE; } diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 98957854b1..d19fc21c7f 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -30,6 +30,15 @@ #include +GQuark gst_plugin_error_quark (void); +#define GST_PLUGIN_ERROR gst_plugin_error_quark () + +typedef enum +{ + GST_PLUGIN_ERROR_MODULE, + GST_PLUGIN_ERROR_DEPENDENCIES +} GstPluginError; + #define GST_PLUGIN(plugin) ((GstPlugin *) (plugin)) typedef struct _GstPlugin GstPlugin; @@ -101,7 +110,7 @@ gboolean gst_plugin_is_loaded (GstPlugin *plugin); GList* gst_plugin_get_feature_list (GstPlugin *plugin); GstPluginFeature* gst_plugin_find_feature (GstPlugin *plugin, const gchar *name, GType type); -gboolean gst_plugin_load_plugin (GstPlugin *plugin); +gboolean gst_plugin_load_plugin (GstPlugin *plugin, GError** error); gboolean gst_plugin_unload_plugin (GstPlugin *plugin); void gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature); diff --git a/gst/registries/gstxmlregistry.c b/gst/registries/gstxmlregistry.c index d896bf08c4..bcf21601df 100644 --- a/gst/registries/gstxmlregistry.c +++ b/gst/registries/gstxmlregistry.c @@ -291,27 +291,47 @@ get_time(const char * path) #define dirmode \ (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -static void gst_xml_registry_get_perms_func (GstXMLRegistry *registry) +static gboolean +make_dir (gchar *filename) { struct stat dirstat; - time_t mod_time = 0; gchar *dirname; + + if (strrchr (filename, '/') == NULL) + return FALSE; + + dirname = g_strndup(filename, strrchr(filename, '/') - filename); + + if (stat (dirname, &dirstat) == -1 && errno == ENOENT) { + if (mkdir (dirname, dirmode) != 0) { + if (make_dir (dirname) != TRUE) { + g_free(dirname); + return FALSE; + } else { + if (mkdir (dirname, dirmode) != 0) + return FALSE; + } + } + } + + g_free(dirname); + return TRUE; +} + +static void +gst_xml_registry_get_perms_func (GstXMLRegistry *registry) +{ + time_t mod_time = 0; FILE *temp; /* if the dir does not exist, make it. if that can't be done, flags = 0x0. if the file can be appended to, it's writable. if it can then be read, it's readable. */ - dirname = g_strndup(registry->location, - strrchr(registry->location, '/') - registry->location); - if (stat(dirname, &dirstat) == -1 && errno == ENOENT) { - if (mkdir(dirname, dirmode) != 0) { - /* we can't do anything with it, leave flags as 0x0 */ - g_free(dirname); - return; - } + if (make_dir (registry->location) != TRUE) { + /* we can't do anything with it, leave flags as 0x0 */ + return; } - g_free(dirname); mod_time = get_time (registry->location); @@ -564,7 +584,8 @@ gst_xml_registry_load (GstRegistry *registry) static GstRegistryReturn gst_xml_registry_load_plugin (GstRegistry *registry, GstPlugin *plugin) { - if (!gst_plugin_load_plugin (plugin)) { + /* FIXME: add gerror support */ + if (!gst_plugin_load_plugin (plugin, NULL)) { return GST_REGISTRY_PLUGIN_LOAD_ERROR; } @@ -1376,11 +1397,11 @@ gst_xml_registry_save (GstRegistry *registry) return TRUE; } -static void +static GList* gst_xml_registry_rebuild_recurse (GstXMLRegistry *registry, const gchar *directory) { GDir *dir; - gboolean loaded = FALSE; + GList *ret = NULL; dir = g_dir_open (directory, 0, NULL); @@ -1396,7 +1417,7 @@ gst_xml_registry_rebuild_recurse (GstXMLRegistry *registry, const gchar *directo } dirname = g_strjoin ("/", directory, dirent, NULL); - gst_xml_registry_rebuild_recurse (registry, dirname); + ret = g_list_concat (ret, gst_xml_registry_rebuild_recurse (registry, dirname)); g_free(dirname); } g_dir_close (dir); @@ -1406,25 +1427,20 @@ gst_xml_registry_rebuild_recurse (GstXMLRegistry *registry, const gchar *directo if ((temp = strstr (directory, ".so")) && (!strcmp (temp, ".so"))) { - GstPlugin *plugin = gst_plugin_new (directory); - - loaded = gst_plugin_load_plugin (plugin); - if (!loaded) { - g_free (plugin->filename); - g_free (plugin); - } - else { - gst_registry_add_plugin (GST_REGISTRY (registry), plugin); - } + ret = g_list_prepend (ret, gst_plugin_new (directory)); } } } + + return ret; } static gboolean gst_xml_registry_rebuild (GstRegistry *registry) { - GList *walk = NULL; + GList *walk = NULL, *plugins = NULL, *prune = NULL; + GError *error = NULL; + gint length; GstXMLRegistry *xmlregistry = GST_XML_REGISTRY (registry); walk = registry->paths; @@ -1434,10 +1450,49 @@ gst_xml_registry_rebuild (GstRegistry *registry) GST_INFO (GST_CAT_PLUGIN_LOADING, "Rebuilding registry %p in directory %s...", registry, path); - gst_xml_registry_rebuild_recurse (xmlregistry, path); + plugins = g_list_concat (plugins, gst_xml_registry_rebuild_recurse (xmlregistry, path)); walk = g_list_next (walk); } + plugins = g_list_reverse (plugins); + + do { + length = g_list_length (plugins); + + walk = plugins; + while (walk) { + g_assert (walk->data); + if (gst_plugin_load_plugin (GST_PLUGIN (walk->data), NULL)) { + prune = g_list_prepend (prune, walk->data); + gst_registry_add_plugin (registry, GST_PLUGIN (walk->data)); + } + + walk = g_list_next (walk); + } + + walk = prune; + while (walk) { + plugins = g_list_remove (plugins, walk->data); + walk = g_list_next (walk); + } + g_list_free (prune); + prune = NULL; + } while (g_list_length (plugins) != length); + + walk = plugins; + while (walk) { + /* should return FALSE */ + gst_plugin_load_plugin (GST_PLUGIN (walk->data), &error); + GST_INFO (GST_CAT_PLUGIN_LOADING, "Plugin %s failed to load: %s\n", + ((GstPlugin*)walk->data)->filename, error->message); + + g_free (((GstPlugin*)walk->data)->filename); + g_free (walk->data); + g_error_free (error); + error = NULL; + + walk = g_list_next (walk); + } return TRUE; } diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c index a309ba06f3..24426faf3f 100644 --- a/plugins/elements/gstidentity.c +++ b/plugins/elements/gstidentity.c @@ -97,10 +97,10 @@ gst_identity_class_init (GstIdentityClass *klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop_based", "loop_based", "loop_based", + g_param_spec_boolean ("loop-based", "Loop-based", "Set to TRUE to use loop-based rather than chain-based scheduling", TRUE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME, - g_param_spec_uint ("sleep_time", "sleep_time", "sleep_time", + g_param_spec_uint ("sleep-time", "Sleep time", "Microseconds to sleep between processing", 0, G_MAXUINT, 0, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE, g_param_spec_uint ("duplicate", "Duplicate Buffers", "Push the buffers N times",