mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
fixes to threaded finalizers
* libguile/finalizers.c (finalization_thread_proc): (run_finalization_thread): (start_finalization_thread): (stop_finalization_thread): Use pthreads + scm_with_guile instead of scm_spawn_thread, to avoid deadlocks.
This commit is contained in:
parent
f9c3584117
commit
2dcf6b5965
1 changed files with 23 additions and 12 deletions
|
@ -171,7 +171,7 @@ queue_finalizer_async (void)
|
||||||
static int finalization_pipe[2];
|
static int finalization_pipe[2];
|
||||||
static scm_i_pthread_mutex_t finalization_thread_lock =
|
static scm_i_pthread_mutex_t finalization_thread_lock =
|
||||||
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
||||||
static SCM finalization_thread = SCM_BOOL_F;
|
static pthread_t finalization_thread;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
notify_finalizers_to_run (void)
|
notify_finalizers_to_run (void)
|
||||||
|
@ -205,7 +205,7 @@ read_finalization_pipe_data (void *data)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SCM
|
static void*
|
||||||
finalization_thread_proc (void *unused)
|
finalization_thread_proc (void *unused)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -216,8 +216,8 @@ finalization_thread_proc (void *unused)
|
||||||
|
|
||||||
if (data.n <= 0 && data.err != EINTR)
|
if (data.n <= 0 && data.err != EINTR)
|
||||||
{
|
{
|
||||||
perror ("error in finalization delivery thread");
|
perror ("error in finalization thread");
|
||||||
return SCM_UNSPECIFIED;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (data.byte)
|
switch (data.byte)
|
||||||
|
@ -226,21 +226,31 @@ finalization_thread_proc (void *unused)
|
||||||
finalization_count += GC_invoke_finalizers ();
|
finalization_count += GC_invoke_finalizers ();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
return SCM_UNSPECIFIED;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
run_finalization_thread (void *arg)
|
||||||
|
{
|
||||||
|
return scm_with_guile (finalization_thread_proc, arg);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
start_finalization_thread (void)
|
start_finalization_thread (void)
|
||||||
{
|
{
|
||||||
scm_i_pthread_mutex_lock (&finalization_thread_lock);
|
scm_i_pthread_mutex_lock (&finalization_thread_lock);
|
||||||
if (scm_is_false (finalization_thread))
|
if (!finalization_thread)
|
||||||
finalization_thread = scm_spawn_thread (finalization_thread_proc, NULL,
|
/* Use the raw pthread API and scm_with_guile, because we don't want
|
||||||
scm_handle_by_message,
|
to block on any lock that scm_spawn_thread might want to take,
|
||||||
"finalization thread");
|
and we don't want to inherit the dynamic state (fluids) of the
|
||||||
|
caller. */
|
||||||
|
if (pthread_create (&finalization_thread, NULL,
|
||||||
|
run_finalization_thread, NULL))
|
||||||
|
perror ("error creating finalization thread");
|
||||||
scm_i_pthread_mutex_unlock (&finalization_thread_lock);
|
scm_i_pthread_mutex_unlock (&finalization_thread_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,11 +258,12 @@ static void
|
||||||
stop_finalization_thread (void)
|
stop_finalization_thread (void)
|
||||||
{
|
{
|
||||||
scm_i_pthread_mutex_lock (&finalization_thread_lock);
|
scm_i_pthread_mutex_lock (&finalization_thread_lock);
|
||||||
if (scm_is_true (finalization_thread))
|
if (finalization_thread)
|
||||||
{
|
{
|
||||||
notify_about_to_fork ();
|
notify_about_to_fork ();
|
||||||
scm_join_thread (finalization_thread);
|
if (pthread_join (finalization_thread, NULL))
|
||||||
finalization_thread = SCM_BOOL_F;
|
perror ("joining finalization thread");
|
||||||
|
finalization_thread = 0;
|
||||||
}
|
}
|
||||||
scm_i_pthread_mutex_unlock (&finalization_thread_lock);
|
scm_i_pthread_mutex_unlock (&finalization_thread_lock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue