gst/gst.c: if we have fork, fork while reading/rebuilding the registry so the parent doesn't take the hit of having a...

Original commit message from CVS:

* gst/gst.c: (init_post):
if we have fork, fork while reading/rebuilding the registry
so the parent doesn't take the hit of having all plugins loaded
in memory.  Fixes #342777.
* configure.ac:
Check if we have fork()
* win32/common/config.h.in:
no fork() on win32
This commit is contained in:
Thomas Vander Stichele 2006-05-28 09:09:03 +00:00
parent d5090022cd
commit dd0456fe1c
4 changed files with 111 additions and 45 deletions

View file

@ -1,3 +1,14 @@
2006-05-28 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/gst.c: (init_post):
if we have fork, fork while reading/rebuilding the registry
so the parent doesn't take the hit of having all plugins loaded
in memory. Fixes #342777.
* configure.ac:
Check if we have fork()
* win32/common/config.h.in:
no fork() on win32
2006-05-26 Jan Schmidt <thaytan@mad.scientist.com> 2006-05-26 Jan Schmidt <thaytan@mad.scientist.com>
* plugins/elements/gstelements.c: * plugins/elements/gstelements.c:

View file

@ -324,6 +324,9 @@ dnl *** checks for library functions ***
AC_CHECK_FUNCS([sigaction]) AC_CHECK_FUNCS([sigaction])
dnl we use fork in the registry code
AC_CHECK_FUNCS([fork])
dnl check for fseeko() dnl check for fseeko()
AC_FUNC_FSEEKO AC_FUNC_FSEEKO
dnl check for ftello() dnl check for ftello()

139
gst/gst.c
View file

@ -104,6 +104,9 @@
#include "gst_private.h" #include "gst_private.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "gst-i18n-lib.h" #include "gst-i18n-lib.h"
#include <locale.h> /* for LC_ALL */ #include <locale.h> /* for LC_ALL */
@ -593,68 +596,114 @@ init_post (void)
GstRegistry *default_registry; GstRegistry *default_registry;
gboolean changed = FALSE; gboolean changed = FALSE;
#ifdef HAVE_FORK
pid_t pid;
#endif
default_registry = gst_registry_get_default (); default_registry = gst_registry_get_default ();
registry_file = g_strdup (g_getenv ("GST_REGISTRY")); registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
if (registry_file == NULL) { if (registry_file == NULL) {
registry_file = g_build_filename (g_get_home_dir (), registry_file = g_build_filename (g_get_home_dir (),
".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".xml", NULL); ".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".xml", NULL);
} }
GST_DEBUG ("Reading registry cache"); #ifdef HAVE_FORK
gst_registry_xml_read_cache (default_registry, registry_file); /* We fork here, and let the child read and possibly rebuild the registry.
* After that, the parent will re-read the freshly generated registry. */
/* GST_PLUGIN_PATH specifies a list of directories to scan for GST_DEBUG ("forking");
* additional plugins. These take precedence over the system plugins */ pid = fork ();
plugin_path = g_getenv ("GST_PLUGIN_PATH"); if (pid == -1) {
if (plugin_path) { GST_ERROR ("Failed to fork()");
char **list; return FALSE;
int i; }
GST_DEBUG ("GST_PLUGIN_PATH set to %s", plugin_path); if (pid == 0) {
list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0); /* this is the child */
for (i = 0; list[i]; i++) { #endif /* HAVE_FORK */
changed |= gst_registry_scan_path (default_registry, list[i]);
GST_DEBUG ("child reading registry cache");
gst_registry_xml_read_cache (default_registry, registry_file);
/* GST_PLUGIN_PATH specifies a list of directories to scan for
* additional plugins. These take precedence over the system plugins */
plugin_path = g_getenv ("GST_PLUGIN_PATH");
if (plugin_path) {
char **list;
int i;
GST_DEBUG ("GST_PLUGIN_PATH set to %s", plugin_path);
list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
for (i = 0; list[i]; i++) {
changed |= gst_registry_scan_path (default_registry, list[i]);
}
g_strfreev (list);
} else {
GST_DEBUG ("GST_PLUGIN_PATH not set");
} }
g_strfreev (list);
} else {
GST_DEBUG ("GST_PLUGIN_PATH not set");
}
/* GST_PLUGIN_SYSTEM_PATH specifies a list of plugins that are always /* GST_PLUGIN_SYSTEM_PATH specifies a list of plugins that are always
* loaded by default. If not set, this defaults to the system-installed * loaded by default. If not set, this defaults to the system-installed
* path, and the plugins installed in the user's home directory */ * path, and the plugins installed in the user's home directory */
plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH"); plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH");
if (plugin_path == NULL) { if (plugin_path == NULL) {
char *home_plugins; char *home_plugins;
GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH not set"); GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH not set");
/* plugins in the user's home directory take precedence over /* plugins in the user's home directory take precedence over
* system-installed ones */ * system-installed ones */
home_plugins = g_build_filename (g_get_home_dir (), home_plugins = g_build_filename (g_get_home_dir (),
".gstreamer-" GST_MAJORMINOR, "plugins", NULL); ".gstreamer-" GST_MAJORMINOR, "plugins", NULL);
changed |= gst_registry_scan_path (default_registry, home_plugins); changed |= gst_registry_scan_path (default_registry, home_plugins);
g_free (home_plugins); g_free (home_plugins);
/* add the main (installed) library path */ /* add the main (installed) library path */
changed |= gst_registry_scan_path (default_registry, PLUGINDIR); changed |= gst_registry_scan_path (default_registry, PLUGINDIR);
} else { } else {
char **list; char **list;
int i; int i;
GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH set to %s", plugin_path); GST_DEBUG ("GST_PLUGIN_SYSTEM_PATH set to %s", plugin_path);
list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0); list = g_strsplit (plugin_path, G_SEARCHPATH_SEPARATOR_S, 0);
for (i = 0; list[i]; i++) { for (i = 0; list[i]; i++) {
changed |= gst_registry_scan_path (default_registry, list[i]); changed |= gst_registry_scan_path (default_registry, list[i]);
}
g_strfreev (list);
} }
g_strfreev (list);
}
if (changed) { if (changed) {
GST_DEBUG ("writing registry cache"); GST_DEBUG ("writing registry cache");
gst_registry_xml_write_cache (default_registry, registry_file); gst_registry_xml_write_cache (default_registry, registry_file);
} }
_gst_registry_remove_cache_plugins (default_registry); _gst_registry_remove_cache_plugins (default_registry);
#ifdef HAVE_FORK
exit (0);
} else {
/* parent */
int status;
pid_t ret;
GST_DEBUG ("parent waiting on child");
ret = waitpid (pid, &status, 0);
GST_DEBUG ("parent done waiting on child");
if (ret == -1) {
GST_ERROR ("error during waitpid: %s", g_strerror (errno));
return FALSE;
}
if (!WIFEXITED (status)) {
GST_ERROR ("child did not exit normally, status: %d", status);
return FALSE;
}
GST_DEBUG ("child exited normally with return value %d",
WEXITSTATUS (status));
GST_DEBUG ("parent reading registry cache");
gst_registry_xml_read_cache (default_registry, registry_file);
}
#endif /* HAVE_FORK */
g_free (registry_file); g_free (registry_file);
} }

View file

@ -84,6 +84,9 @@
/* Define to 1 if you have the `fgetpos' function. */ /* Define to 1 if you have the `fgetpos' function. */
#define HAVE_FGETPOS 1 #define HAVE_FGETPOS 1
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO #undef HAVE_FSEEKO