From 8bf3d8cec2283bce489bc8f47692040bf9205df0 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Fri, 6 Feb 2009 09:49:34 +0000 Subject: [PATCH] registry: Support installed/uninstalled plugin-scanner helper Add a simple version check when starting the plugin-scanner so we can verify we're talking to one that talks the same language. First try a plugin-scanner in the installed path, then try one via the GST_PLUGIN_SCANNER env var if that doesn't work. Update the uninstalled script. Install the plugin-scanner to the libexec dir --- configure.ac | 5 ++ docs/faq/gst-uninstalled | 2 + gst/gstpluginloader.c | 112 +++++++++++++++++++++++++++++++++---------- libs/gst/helpers/Makefile.am | 5 +- 4 files changed, 96 insertions(+), 28 deletions(-) diff --git a/configure.ac b/configure.ac index 072b332..6f30757 100644 --- a/configure.ac +++ b/configure.ac @@ -654,6 +654,11 @@ dnl LDFLAGS for plugins; includes GST_ALL_LDFLAGS GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^[_]*gst_plugin_desc\$\$' $GST_ALL_LDFLAGS" AC_SUBST(GST_PLUGIN_LDFLAGS, "$GST_PLUGIN_LDFLAGS") +dnl plugin scanner locations +AS_AC_EXPAND(GST_PLUGIN_SCANNER_INSTALLED,${libexecdir}/plugin-scanner) +AC_DEFINE_UNQUOTED(GST_PLUGIN_SCANNER_INSTALLED, + "$GST_PLUGIN_SCANNER_INSTALLED", [location of the installed plugin-scanner]) + SHAVE_INIT([common],[enable]) dnl things for our internal libcheck diff --git a/docs/faq/gst-uninstalled b/docs/faq/gst-uninstalled index 8c56286..2c28b8c 100755 --- a/docs/faq/gst-uninstalled +++ b/docs/faq/gst-uninstalled @@ -123,6 +123,8 @@ export GST_PLUGIN_SYSTEM_PATH= # by an installed copy rm -f $GST/gstreamer/registry.xml 2>/dev/null export GST_REGISTRY=$GST/gstreamer/registry.dat +# Point at the uninstalled plugin scanner +export GST_PLUGIN_SCANNER=$GST/gstreamer/libs/gst/helpers/plugin-scanner # once MANPATH is set, it needs at least an "empty"component to keep pulling # in the system-configured man paths from man.config diff --git a/gst/gstpluginloader.c b/gst/gstpluginloader.c index 2679a0c..8f9bffe 100644 --- a/gst/gstpluginloader.c +++ b/gst/gstpluginloader.c @@ -40,6 +40,9 @@ #include #include +/* IMPORTANT: Bump the version number if the plugin loader protocol changes */ +static const guint32 loader_protocol_version = 1; + #define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING static GstPluginLoader *plugin_loader_new (GstRegistry * registry); @@ -85,6 +88,8 @@ struct _GstPluginLoader gboolean rx_done; gboolean rx_got_sync; + guint32 got_version; + /* Head and tail of the pending plugins list. List of PendingPluginEntry structs */ GList *pending_plugins; @@ -95,13 +100,13 @@ struct _GstPluginLoader #define PACKET_LOAD_PLUGIN 2 #define PACKET_SYNC 3 #define PACKET_PLUGIN_DETAILS 4 +#define PACKET_VERSION 5 #define BUF_INIT_SIZE 512 #define BUF_GROW_EXTRA 512 #define HEADER_SIZE 8 #define ALIGNMENT (sizeof (void *)) - static gboolean gst_plugin_loader_spawn (GstPluginLoader * loader); static void put_packet (GstPluginLoader * loader, guint type, guint32 tag, const guint8 * payload, guint32 payload_len); @@ -112,6 +117,7 @@ static gboolean plugin_loader_load_and_sync (GstPluginLoader * l, static void plugin_loader_create_blacklist_plugin (GstPluginLoader * l, PendingPluginEntry * entry); static void plugin_loader_cleanup_child (GstPluginLoader * loader); +static gboolean plugin_loader_sync_with_child (GstPluginLoader * l); static GstPluginLoader * plugin_loader_new (GstRegistry * registry) @@ -274,6 +280,19 @@ restart: } static gboolean +plugin_loader_sync_with_child (GstPluginLoader * l) +{ + put_packet (l, PACKET_SYNC, 0, NULL, 0); + + l->rx_got_sync = FALSE; + while (!l->rx_got_sync) { + if (!exchange_packets (l)) + return FALSE; + } + return TRUE; +} + +static gboolean plugin_loader_load_and_sync (GstPluginLoader * l, PendingPluginEntry * entry) { gint len; @@ -284,15 +303,8 @@ plugin_loader_load_and_sync (GstPluginLoader * l, PendingPluginEntry * entry) len = strlen (entry->filename); put_packet (l, PACKET_LOAD_PLUGIN, entry->tag, (guint8 *) entry->filename, len + 1); - put_packet (l, PACKET_SYNC, 0, NULL, 0); - l->rx_got_sync = FALSE; - while (!l->rx_got_sync) { - if (!exchange_packets (l)) - return FALSE; - } - - return TRUE; + return plugin_loader_sync_with_child (l); } static void @@ -320,23 +332,16 @@ plugin_loader_create_blacklist_plugin (GstPluginLoader * l, } static gboolean -gst_plugin_loader_spawn (GstPluginLoader * loader) +gst_plugin_loader_try_helper (GstPluginLoader * loader, gchar * location) { - if (loader->child_running) - return TRUE; + char *argv[] = { location, "-l", NULL }; - { - /* FIXME: Find the plugin-scanner! */ - char *helper_bin = - "/home/jan/devel/gstreamer/head/gstreamer/libs/gst/helpers/plugin-scanner"; - char *argv[] = { helper_bin, "-l", NULL }; - - if (!g_spawn_async_with_pipes (NULL, argv, NULL, - G_SPAWN_DO_NOT_REAP_CHILD /* | G_SPAWN_STDERR_TO_DEV_NULL */ , - NULL, NULL, &loader->child_pid, &loader->fd_w.fd, &loader->fd_r.fd, - NULL, NULL)) - return FALSE; - } + GST_LOG ("Trying to spawn plugin-scanner helper at %s", location); + if (!g_spawn_async_with_pipes (NULL, argv, NULL, + G_SPAWN_DO_NOT_REAP_CHILD /* | G_SPAWN_STDERR_TO_DEV_NULL */ , + NULL, NULL, &loader->child_pid, &loader->fd_w.fd, &loader->fd_r.fd, + NULL, NULL)) + return FALSE; gst_poll_add_fd (loader->fdset, &loader->fd_w); gst_poll_add_fd (loader->fdset, &loader->fd_r); @@ -345,11 +350,53 @@ gst_plugin_loader_spawn (GstPluginLoader * loader) loader->tx_buf_write = loader->tx_buf_read = 0; + loader->got_version = (guint32) (-1); + put_packet (loader, PACKET_VERSION, 0, NULL, 0); + if (!plugin_loader_sync_with_child (loader)) + return FALSE; + + GST_LOG ("Got VERSION %u from child. Ours is %u", loader->got_version, + loader_protocol_version); + if (loader->got_version != loader_protocol_version) + return FALSE; + loader->child_running = TRUE; return TRUE; } +static gboolean +gst_plugin_loader_spawn (GstPluginLoader * loader) +{ + char *helper_bin; + gboolean res; + + if (loader->child_running) + return TRUE; + + /* Find the plugin-scanner, first try installed then by env-var */ + helper_bin = g_strdup (GST_PLUGIN_SCANNER_INSTALLED); + res = gst_plugin_loader_try_helper (loader, helper_bin); + g_free (helper_bin); + + if (!res) { + /* Try the GST_PLUGIN_SCANNER env var */ + const gchar *env = g_getenv ("GST_PLUGIN_SCANNER"); + if (env != NULL) { + GST_LOG ("Installed plugin scanner failed. " + "Trying GST_PLUGIN_SCANNER env var: %s", env); + helper_bin = g_strdup (env); + res = gst_plugin_loader_try_helper (loader, helper_bin); + g_free (helper_bin); + } else { + GST_LOG ("Installed plugin scanner failed and " + "GST_PLUGIN_SCANNER env var not set. No plugin-scanner available"); + } + } + + return loader->child_running; +} + static void plugin_loader_cleanup_child (GstPluginLoader * l) { @@ -645,11 +692,26 @@ handle_rx_packet (GstPluginLoader * l, case PACKET_SYNC: if (l->is_child) { /* Respond with our reply - also a sync */ - put_packet (l, PACKET_SYNC, 0, NULL, 0); + put_packet (l, PACKET_SYNC, tag, NULL, 0); GST_LOG ("Got SYNC in child - replying"); } else l->rx_got_sync = TRUE; break; + case PACKET_VERSION: + if (l->is_child) { + /* Respond with our reply - a version packet, with the version */ + guint32 val; + GST_WRITE_UINT32_BE (&val, loader_protocol_version); + put_packet (l, PACKET_VERSION, tag, (guint8 *) & val, sizeof (guint32)); + GST_LOG ("Got VERSION in child - replying %u", loader_protocol_version); + } else { + if (payload_len == sizeof (loader_protocol_version)) { + l->got_version = GST_READ_UINT32_BE (payload); + } else { + res = FALSE; + } + } + break; default: return FALSE; /* Invalid packet -> something is wrong */ } diff --git a/libs/gst/helpers/Makefile.am b/libs/gst/helpers/Makefile.am index 419762b..b9ca33c 100644 --- a/libs/gst/helpers/Makefile.am +++ b/libs/gst/helpers/Makefile.am @@ -1,6 +1,5 @@ -# helpers_PROGRAMS = plugin-scanner -# FIXME: Subst helpersdir in configure.ac -noinst_PROGRAMS = plugin-scanner +helpers_PROGRAMS = plugin-scanner +helpersdir=$(libexecdir) plugin_scanner_SOURCES = plugin-scanner.c plugin_scanner_CFLAGS = $(GST_OBJ_CFLAGS) -- 2.7.4