From: Jan Schmidt Date: Fri, 23 Jan 2009 15:47:08 +0000 (+0000) Subject: Plugin loader phase 2 X-Git-Tag: RELEASE-0.10.26~456 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38083fb0c80b246145bf94734b60789a009e1aeb;p=platform%2Fupstream%2Fgstreamer.git Plugin loader phase 2 phase 2 - make the plugin loader receive the list of plugins to load and send back the results asynchronously, so we don't context switch back and forth so much. --- diff --git a/gst/gstpluginloader.c b/gst/gstpluginloader.c index 3fd29cc..8ea7959 100644 --- a/gst/gstpluginloader.c +++ b/gst/gstpluginloader.c @@ -45,12 +45,20 @@ static GstPluginLoader *plugin_loader_new (GstRegistry * registry); static gboolean plugin_loader_free (GstPluginLoader * loader); static gboolean plugin_loader_load (GstPluginLoader * loader, - const gchar * filename); + const gchar * filename, off_t file_size, time_t file_mtime); const GstPluginLoaderFuncs _priv_gst_plugin_loader_funcs = { plugin_loader_new, plugin_loader_free, plugin_loader_load }; +typedef struct _PendingPluginEntry +{ + guint32 tag; + gchar *filename; + off_t file_size; + time_t file_mtime; +} PendingPluginEntry; + struct _GstPluginLoader { GstRegistry *registry; @@ -75,6 +83,11 @@ struct _GstPluginLoader guint8 *rx_buf; guint rx_buf_size; gboolean rx_done; + + /* Head and tail of the pending plugins list. List of + PendingPluginEntry structs */ + GList *pending_plugins; + GList *pending_plugins_tail; }; #define PACKET_EXIT 1 @@ -118,6 +131,7 @@ plugin_loader_new (GstRegistry * registry) static gboolean plugin_loader_free (GstPluginLoader * loader) { + GList *cur; gboolean got_plugin_details; fsync (loader->fd_w.fd); @@ -154,14 +168,28 @@ plugin_loader_free (GstPluginLoader * loader) got_plugin_details = loader->got_plugin_details; + /* Free any pending plugin entries */ + cur = loader->pending_plugins; + while (cur) { + PendingPluginEntry *entry = (PendingPluginEntry *) (cur->data); + g_free (entry->filename); + g_free (entry); + + cur = g_list_delete_link (cur, cur); + } + g_free (loader); return got_plugin_details; } static gboolean -plugin_loader_load (GstPluginLoader * loader, const gchar * filename) +plugin_loader_load (GstPluginLoader * loader, const gchar * filename, + off_t file_size, time_t file_mtime) { + gint len; + PendingPluginEntry *entry; + if (!loader->child_started) { if (!gst_plugin_loader_spawn (loader)) return FALSE; @@ -171,10 +199,22 @@ plugin_loader_load (GstPluginLoader * loader, const gchar * filename) GST_LOG_OBJECT (loader->registry, "Sending file %s to child. tag %u", filename, loader->next_tag); - put_packet (loader, PACKET_LOAD_PLUGIN, loader->next_tag, - (guint8 *) filename, strlen (filename) + 1); + entry = g_new (PendingPluginEntry, 1); + entry->tag = loader->next_tag++; + entry->filename = g_strdup (filename); + entry->file_size = file_size; + entry->file_mtime = file_mtime; + loader->pending_plugins_tail = + g_list_append (loader->pending_plugins_tail, entry); + + if (loader->pending_plugins == NULL) + loader->pending_plugins = loader->pending_plugins_tail; + else + loader->pending_plugins_tail = g_list_next (loader->pending_plugins_tail); - loader->next_tag++; + len = strlen (filename); + put_packet (loader, PACKET_LOAD_PLUGIN, entry->tag, + (guint8 *) filename, len + 1); if (!exchange_packets (loader)) return FALSE; @@ -412,9 +452,35 @@ handle_rx_packet (GstPluginLoader * l, break; case PACKET_PLUGIN_DETAILS:{ gchar *tmp = (gchar *) payload; + PendingPluginEntry *entry = NULL; + GList *cur; GST_DEBUG_OBJECT (l->registry, - "child loaded plugin w/ tag %u. %d bytes info", tag, payload_len); + "Received plugin details from child w/ tag %u. %d bytes info", + tag, payload_len); + + /* Assume that tagged details come back in the order + * we requested, and delete anything before this one */ + cur = l->pending_plugins; + while (cur) { + PendingPluginEntry *e = (PendingPluginEntry *) (cur->data); + + if (e->tag > tag) + break; + + cur = g_list_delete_link (cur, cur); + + if (e->tag == tag) { + entry = e; + break; + } else { + g_free (e->filename); + g_free (e); + } + } + l->pending_plugins = cur; + if (cur == NULL) + l->pending_plugins_tail = NULL; if (payload_len > 0) { GstPlugin *newplugin; @@ -428,6 +494,32 @@ handle_rx_packet (GstPluginLoader * l, /* We got a set of plugin details - remember it for later */ l->got_plugin_details = TRUE; + } else if (entry != NULL) { + /* Create a dummy entry for this file to prevent scanning every time */ + GstPlugin *plugin = g_object_new (GST_TYPE_PLUGIN, NULL); + + plugin->filename = g_strdup (entry->filename); + plugin->file_mtime = entry->file_mtime; + plugin->file_size = entry->file_size; + + plugin->basename = g_path_get_basename (plugin->filename); + plugin->desc.name = g_intern_string (plugin->basename); + plugin->desc.description = g_strdup_printf ("Dummy plugin for file %s", + plugin->filename); + plugin->desc.version = g_intern_string ("0.0.0"); + plugin->desc.license = g_intern_string ("DUMMY"); + plugin->desc.source = plugin->desc.license; + plugin->desc.package = plugin->desc.license; + plugin->desc.origin = plugin->desc.license; + + GST_DEBUG ("Adding dummy plugin '%s'", plugin->desc.name); + gst_registry_add_plugin (l->registry, plugin); + l->got_plugin_details = TRUE; + } + + if (entry != NULL) { + g_free (entry->filename); + g_free (entry); } break; diff --git a/gst/gstpluginloader.h b/gst/gstpluginloader.h index cae2634..b2dbabd 100644 --- a/gst/gstpluginloader.h +++ b/gst/gstpluginloader.h @@ -28,7 +28,8 @@ typedef struct _GstPluginLoader GstPluginLoader; typedef struct _GstPluginLoaderFuncs { GstPluginLoader * (*create)(GstRegistry *registry); gboolean (*destroy)(GstPluginLoader *loader); - gboolean (*load)(GstPluginLoader *loader, const gchar *filename); + gboolean (*load)(GstPluginLoader *loader, const gchar *filename, + off_t file_size, time_t file_mtime); } GstPluginLoaderFuncs; extern const GstPluginLoaderFuncs _priv_gst_plugin_loader_funcs; diff --git a/gst/gstregistry.c b/gst/gstregistry.c index b179fa5..591e798 100644 --- a/gst/gstregistry.c +++ b/gst/gstregistry.c @@ -878,7 +878,7 @@ clear_scan_context (GstRegistryScanContext * context) static gboolean gst_registry_scan_plugin_file (GstRegistryScanContext * context, - const gchar * filename) + const gchar * filename, off_t file_size, time_t file_mtime) { gboolean changed = FALSE; GstPlugin *newplugin = NULL; @@ -895,7 +895,8 @@ gst_registry_scan_plugin_file (GstRegistryScanContext * context, if (context->helper_state == REGISTRY_SCAN_HELPER_RUNNING) { GST_DEBUG ("Using scan-helper to load plugin %s", filename); - if (!_priv_gst_plugin_loader_funcs.load (context->helper, filename)) { + if (!_priv_gst_plugin_loader_funcs.load (context->helper, + filename, file_size, file_mtime)) { g_warning ("External plugin loader failed..."); context->helper_state = REGISTRY_SCAN_HELPER_DISABLED; } @@ -1027,14 +1028,16 @@ gst_registry_scan_path_level (GstRegistryScanContext * context, (gint64) plugin->file_size, (gint64) file_status.st_size, env_vars_changed, deps_changed); gst_registry_remove_plugin (context->registry, plugin); - changed |= gst_registry_scan_plugin_file (context, filename); + changed |= gst_registry_scan_plugin_file (context, filename, + file_status.st_size, file_status.st_mtime); } gst_object_unref (plugin); } else { GST_DEBUG_OBJECT (context->registry, "file %s not yet in registry", filename); - changed |= gst_registry_scan_plugin_file (context, filename); + changed |= gst_registry_scan_plugin_file (context, filename, + file_status.st_size, file_status.st_mtime); } g_free (filename);