summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2009-01-23 15:47:08 +0000
committerJan Schmidt <thaytan@noraisin.net>2009-10-06 19:51:42 +0100
commit38083fb0c80b246145bf94734b60789a009e1aeb (patch)
tree6671fc1e84445ea65dd2ec3a480bedcdaa50bf56 /gst
parent51675e0c2a1bcf0263e45a74ab0da081469b3236 (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.c104
-rw-r--r--gst/gstpluginloader.h3
-rw-r--r--gst/gstregistry.c11
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);