mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-27 06:26:15 +01:00
mainloop: detect fork() and abort
Abort if the child process returns to the mainloop after a fork(). https://bugzilla.gnome.org/show_bug.cgi?id=658999
This commit is contained in:
parent
01f9479438
commit
01ed78d525
41
glib/gmain.c
41
glib/gmain.c
@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
#include "glib-unix.h"
|
#include "glib-unix.h"
|
||||||
|
#include <pthread.h>
|
||||||
#ifdef HAVE_EVENTFD
|
#ifdef HAVE_EVENTFD
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#endif
|
#endif
|
||||||
@ -174,6 +175,10 @@
|
|||||||
* <graphic fileref="mainloop-states.gif" format="GIF"></graphic>
|
* <graphic fileref="mainloop-states.gif" format="GIF"></graphic>
|
||||||
* </figure>
|
* </figure>
|
||||||
* </refsect2>
|
* </refsect2>
|
||||||
|
*
|
||||||
|
* On Unix, the GLib mainloop is incompatible with fork(). Any program
|
||||||
|
* using the mainloop must either exec() or exit() from the child
|
||||||
|
* without returning to the mainloop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
@ -374,6 +379,7 @@ static gboolean g_idle_dispatch (GSource *source,
|
|||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
static GMainContext *glib_worker_context;
|
static GMainContext *glib_worker_context;
|
||||||
|
static gboolean g_main_context_fork_detected;
|
||||||
|
|
||||||
G_LOCK_DEFINE_STATIC (main_loop);
|
G_LOCK_DEFINE_STATIC (main_loop);
|
||||||
static GMainContext *default_main_context;
|
static GMainContext *default_main_context;
|
||||||
@ -497,6 +503,14 @@ g_main_context_unref (GMainContext *context)
|
|||||||
g_free (context);
|
g_free (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
static void
|
||||||
|
g_main_context_forked (void)
|
||||||
|
{
|
||||||
|
g_main_context_fork_detected = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_main_context_new:
|
* g_main_context_new:
|
||||||
*
|
*
|
||||||
@ -507,25 +521,27 @@ g_main_context_unref (GMainContext *context)
|
|||||||
GMainContext *
|
GMainContext *
|
||||||
g_main_context_new (void)
|
g_main_context_new (void)
|
||||||
{
|
{
|
||||||
|
static gsize initialised;
|
||||||
GMainContext *context;
|
GMainContext *context;
|
||||||
|
|
||||||
g_thread_init_glib ();
|
g_thread_init_glib ();
|
||||||
|
|
||||||
context = g_new0 (GMainContext, 1);
|
if (g_once_init_enter (&initialised))
|
||||||
|
{
|
||||||
#ifdef G_MAIN_POLL_DEBUG
|
#ifdef G_MAIN_POLL_DEBUG
|
||||||
{
|
if (getenv ("G_MAIN_POLL_DEBUG") != NULL)
|
||||||
static gboolean beenhere = FALSE;
|
_g_main_poll_debug = TRUE;
|
||||||
|
|
||||||
if (!beenhere)
|
|
||||||
{
|
|
||||||
if (getenv ("G_MAIN_POLL_DEBUG") != NULL)
|
|
||||||
_g_main_poll_debug = TRUE;
|
|
||||||
beenhere = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
pthread_atfork (NULL, NULL, g_main_context_forked);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_once_init_leave (&initialised, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
context = g_new0 (GMainContext, 1);
|
||||||
|
|
||||||
g_static_mutex_init (&context->mutex);
|
g_static_mutex_init (&context->mutex);
|
||||||
|
|
||||||
context->owner = NULL;
|
context->owner = NULL;
|
||||||
@ -2976,6 +2992,7 @@ g_main_context_iterate (GMainContext *context,
|
|||||||
if (!block)
|
if (!block)
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
|
||||||
|
g_assert (!g_main_context_fork_detected);
|
||||||
g_main_context_poll (context, timeout, max_priority, fds, nfds);
|
g_main_context_poll (context, timeout, max_priority, fds, nfds);
|
||||||
|
|
||||||
some_ready = g_main_context_check (context, max_priority, fds, nfds);
|
some_ready = g_main_context_check (context, max_priority, fds, nfds);
|
||||||
|
Loading…
Reference in New Issue
Block a user