From: Thomas Vander Stichele Date: Sun, 28 May 2006 09:09:03 +0000 (+0000) Subject: gst/gst.c: if we have fork, fork while reading/rebuilding the registry so the parent... X-Git-Tag: RELEASE-0_10_7~46 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dd0456fe1c3b931973960eb13622cf79c9e359b3;p=platform%2Fupstream%2Fgstreamer.git 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 --- diff --git a/ChangeLog b/ChangeLog index 21ee4e8..c2a2d1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2006-05-28 Thomas Vander Stichele + + * 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 * plugins/elements/gstelements.c: diff --git a/configure.ac b/configure.ac index cdaa76e..41c96ad 100644 --- a/configure.ac +++ b/configure.ac @@ -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() diff --git a/gst/gst.c b/gst/gst.c index 2b1682e..c425a47 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -104,6 +104,9 @@ #include "gst_private.h" #include #include +#include +#include +#include #include "gst-i18n-lib.h" #include /* 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); - - /* 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"); +#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_DEBUG ("forking"); + pid = fork (); + if (pid == -1) { + GST_ERROR ("Failed to fork()"); + return FALSE; } - /* 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; + 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"); + } - GST_DEBUG ("GST_PLUGIN_SYSTEM_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_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); + + /* 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]); + } + g_strfreev (list); + } - /* 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); + if (changed) { + GST_DEBUG ("writing registry cache"); + gst_registry_xml_write_cache (default_registry, registry_file); + } + + _gst_registry_remove_cache_plugins (default_registry); - /* add the main (installed) library path */ - changed |= gst_registry_scan_path (default_registry, PLUGINDIR); +#ifdef HAVE_FORK + exit (0); } else { - char **list; - int i; + /* 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; + } - 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]); + if (!WIFEXITED (status)) { + GST_ERROR ("child did not exit normally, status: %d", status); + return FALSE; } - g_strfreev (list); - } - if (changed) { - GST_DEBUG ("writing registry cache"); - gst_registry_xml_write_cache (default_registry, registry_file); + 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); } - - _gst_registry_remove_cache_plugins (default_registry); +#endif /* HAVE_FORK */ g_free (registry_file); } diff --git a/win32/common/config.h.in b/win32/common/config.h.in index 60b1d63..671697a 100644 --- a/win32/common/config.h.in +++ b/win32/common/config.h.in @@ -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