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>
* plugins/elements/gstelements.c:

View file

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

139
gst/gst.c
View file

@ -104,6 +104,9 @@
#include "gst_private.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "gst-i18n-lib.h"
#include <locale.h> /* for LC_ALL */
@ -593,68 +596,114 @@ init_post (void)
GstRegistry *default_registry;
gboolean changed = FALSE;
#ifdef HAVE_FORK
pid_t pid;
#endif
default_registry = gst_registry_get_default ();
registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
if (registry_file == NULL) {
registry_file = g_build_filename (g_get_home_dir (),
".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".xml", NULL);
}
GST_DEBUG ("Reading registry cache");
gst_registry_xml_read_cache (default_registry, registry_file);
#ifdef HAVE_FORK
/* 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
* 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 ("forking");
pid = fork ();
if (pid == -1) {
GST_ERROR ("Failed to fork()");
return FALSE;
}
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]);
if (pid == 0) {
/* this is the child */
#endif /* HAVE_FORK */
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
* loaded by default. If not set, this defaults to the system-installed
* path, and the plugins installed in the user's home directory */
plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH");
if (plugin_path == NULL) {
char *home_plugins;
/* GST_PLUGIN_SYSTEM_PATH specifies a list of plugins that are always
* loaded by default. If not set, this defaults to the system-installed
* path, and the plugins installed in the user's home directory */
plugin_path = g_getenv ("GST_PLUGIN_SYSTEM_PATH");
if (plugin_path == NULL) {
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
* system-installed ones */
home_plugins = g_build_filename (g_get_home_dir (),
".gstreamer-" GST_MAJORMINOR, "plugins", NULL);
changed |= gst_registry_scan_path (default_registry, home_plugins);
g_free (home_plugins);
/* plugins in the user's home directory take precedence over
* system-installed ones */
home_plugins = g_build_filename (g_get_home_dir (),
".gstreamer-" GST_MAJORMINOR, "plugins", NULL);
changed |= gst_registry_scan_path (default_registry, home_plugins);
g_free (home_plugins);
/* add the main (installed) library path */
changed |= gst_registry_scan_path (default_registry, PLUGINDIR);
} else {
char **list;
int i;
/* add the main (installed) library path */
changed |= gst_registry_scan_path (default_registry, PLUGINDIR);
} else {
char **list;
int i;
GST_DEBUG ("GST_PLUGIN_SYSTEM_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]);
GST_DEBUG ("GST_PLUGIN_SYSTEM_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);
}
g_strfreev (list);
}
if (changed) {
GST_DEBUG ("writing registry cache");
gst_registry_xml_write_cache (default_registry, registry_file);
}
if (changed) {
GST_DEBUG ("writing registry cache");
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);
}

View file

@ -84,6 +84,9 @@
/* Define to 1 if you have the `fgetpos' function. */
#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. */
#undef HAVE_FSEEKO