[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#41948: Shepherd deadlocks
From: |
Ludovic Courtès |
Subject: |
bug#41948: Shepherd deadlocks |
Date: |
Sat, 08 May 2021 11:43:07 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) |
Hi,
Mathieu Othacehe <othacehe@gnu.org> skribis:
> Those two finalizer threads share the same pipe. When we try to
> stop the finalizer thread in Shepherd, right before forking a new
> process, we send a '\1' byte to the finalizer pipe.
>
> 1 write(6, "\1", 1 <unfinished ...>
>
>
> which is received by (line 183597):
>
> 253 <... read resumed>"\1", 1) = 1
>
> the marionette finalizer thread. Then, we pthread_join the Shepherd
> finalizer thread, which never stops! Quite unfortunate.
And here’s the patch for this pipe: it closes the finalizer pipe
pre-fork, and it gets reopened lazily.
Together with the ‘sleep_pipe’ patch, it appears to fix the problems
described here.
Ludo’.
diff --git a/libguile/finalizers.c b/libguile/finalizers.c
index 0ae165fd1..5ddc7dbef 100644
--- a/libguile/finalizers.c
+++ b/libguile/finalizers.c
@@ -24,6 +24,7 @@
# include <config.h>
#endif
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <full-write.h>
@@ -170,7 +171,7 @@ queue_finalizer_async (void)
#if SCM_USE_PTHREAD_THREADS
-static int finalization_pipe[2];
+static int finalization_pipe[2] = { -1, -1 };
static scm_i_pthread_mutex_t finalization_thread_lock =
SCM_I_PTHREAD_MUTEX_INITIALIZER;
static pthread_t finalization_thread;
@@ -254,6 +255,13 @@ start_finalization_thread (void)
scm_i_pthread_mutex_lock (&finalization_thread_lock);
if (!finalization_thread_is_running)
{
+ assert (finalization_pipe[0] == -1);
+
+ if (pipe2 (finalization_pipe, O_CLOEXEC) != 0)
+ scm_syserror (NULL);
+
+ GC_set_finalizer_notifier (notify_finalizers_to_run);
+
/* Use the raw pthread API and scm_with_guile, because we don't want
to block on any lock that scm_spawn_thread might want to take,
and we don't want to inherit the dynamic state (fluids) of the
@@ -276,6 +284,12 @@ stop_finalization_thread (void)
notify_about_to_fork ();
if (pthread_join (finalization_thread, NULL))
perror ("joining finalization thread");
+
+ close (finalization_pipe[0]);
+ close (finalization_pipe[1]);
+ finalization_pipe[0] = -1;
+ finalization_pipe[1] = -1;
+
finalization_thread_is_running = 0;
}
scm_i_pthread_mutex_unlock (&finalization_thread_lock);
@@ -284,7 +298,6 @@ stop_finalization_thread (void)
static void
spawn_finalizer_thread (void)
{
- GC_set_finalizer_notifier (notify_finalizers_to_run);
start_finalization_thread ();
}
@@ -368,8 +381,6 @@ scm_set_automatic_finalization_enabled (int enabled_p)
if (enabled_p)
{
#if SCM_USE_PTHREAD_THREADS
- if (pipe2 (finalization_pipe, O_CLOEXEC) != 0)
- scm_syserror (NULL);
GC_set_finalizer_notifier (spawn_finalizer_thread);
#else
GC_set_finalizer_notifier (queue_finalizer_async);
@@ -381,10 +392,6 @@ scm_set_automatic_finalization_enabled (int enabled_p)
#if SCM_USE_PTHREAD_THREADS
stop_finalization_thread ();
- close (finalization_pipe[0]);
- close (finalization_pipe[1]);
- finalization_pipe[0] = -1;
- finalization_pipe[1] = -1;
#endif
}
@@ -423,10 +430,6 @@ scm_init_finalizer_thread (void)
{
#if SCM_USE_PTHREAD_THREADS
if (automatic_finalization_p)
- {
- if (pipe2 (finalization_pipe, O_CLOEXEC) != 0)
- scm_syserror (NULL);
GC_set_finalizer_notifier (spawn_finalizer_thread);
- }
#endif
}