diff options
author | Jan Schmidt <thaytan@noraisin.net> | 2009-01-23 15:47:08 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@noraisin.net> | 2009-10-06 19:51:42 +0100 |
commit | 38083fb0c80b246145bf94734b60789a009e1aeb (patch) | |
tree | 6671fc1e84445ea65dd2ec3a480bedcdaa50bf56 /gst | |
parent | 51675e0c2a1bcf0263e45a74ab0da081469b3236 (diff) |
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.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/gstpluginloader.c | 104 | ||||
-rw-r--r-- | gst/gstpluginloader.h | 3 | ||||
-rw-r--r-- | gst/gstregistry.c | 11 |
3 files changed, 107 insertions, 11 deletions
diff --git a/gst/gstpluginloader.c b/gst/gstpluginloader.c index 3fd29cce3..8ea795927 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 cae263497..b2dbabd97 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 b179fa582..591e798fc 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); |