mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Fix support for threads already known to GC
* libguile/threads.h (scm_i_thread): Add bool tracking whether the thread needs to be unregistered from libgc. * libguile/threads.c (guilify_self_1): Add needs_unregister arg. (on_thread_exit): Only unregister thread if the thread needs it. (scm_i_init_thread_for_guile): A thread needs unregistering if GC_register_my_thread succeeded. (scm_threads_prehistory): Don't unregister initial thread. Fixes #19523. Thanks to Anthonin Bonnefoy for the report.
This commit is contained in:
parent
631e9901d8
commit
4c3bea3dba
2 changed files with 17 additions and 5 deletions
|
@ -372,7 +372,7 @@ static SCM default_dynamic_state;
|
|||
/* Perform first stage of thread initialisation, in non-guile mode.
|
||||
*/
|
||||
static void
|
||||
guilify_self_1 (struct GC_stack_base *base)
|
||||
guilify_self_1 (struct GC_stack_base *base, int needs_unregister)
|
||||
{
|
||||
scm_i_thread t;
|
||||
|
||||
|
@ -410,6 +410,7 @@ guilify_self_1 (struct GC_stack_base *base)
|
|||
|
||||
t.exited = 0;
|
||||
t.guile_mode = 0;
|
||||
t.needs_unregister = needs_unregister;
|
||||
|
||||
/* The switcheroo. */
|
||||
{
|
||||
|
@ -523,8 +524,13 @@ on_thread_exit (void *v)
|
|||
scm_i_vm_free_stack (vp);
|
||||
}
|
||||
|
||||
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||
scm_i_current_thread = NULL;
|
||||
#endif
|
||||
|
||||
#if SCM_USE_PTHREAD_THREADS
|
||||
GC_unregister_my_thread ();
|
||||
if (t->needs_unregister)
|
||||
GC_unregister_my_thread ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -586,6 +592,8 @@ scm_i_init_thread_for_guile (struct GC_stack_base *base,
|
|||
}
|
||||
else
|
||||
{
|
||||
int needs_unregister = 0;
|
||||
|
||||
/* Guile is already initialized, but this thread enters it for
|
||||
the first time. Only initialize this thread.
|
||||
*/
|
||||
|
@ -593,10 +601,11 @@ scm_i_init_thread_for_guile (struct GC_stack_base *base,
|
|||
|
||||
/* Register this thread with libgc. */
|
||||
#if SCM_USE_PTHREAD_THREADS
|
||||
GC_register_my_thread (base);
|
||||
if (GC_register_my_thread (base) == GC_SUCCESS)
|
||||
needs_unregister = 1;
|
||||
#endif
|
||||
|
||||
guilify_self_1 (base);
|
||||
guilify_self_1 (base, needs_unregister);
|
||||
guilify_self_2 (dynamic_state);
|
||||
}
|
||||
return 1;
|
||||
|
@ -1782,7 +1791,7 @@ scm_threads_prehistory (void *base)
|
|||
GC_MAKE_PROC (GC_new_proc (thread_mark), 0),
|
||||
0, 1);
|
||||
|
||||
guilify_self_1 ((struct GC_stack_base *) base);
|
||||
guilify_self_1 ((struct GC_stack_base *) base, 0);
|
||||
}
|
||||
|
||||
scm_t_bits scm_tc16_thread;
|
||||
|
|
|
@ -59,6 +59,9 @@ typedef struct scm_i_thread {
|
|||
|
||||
/* Boolean indicating whether the thread is in guile mode. */
|
||||
int guile_mode;
|
||||
/* Boolean indicating whether to call GC_unregister_my_thread () when
|
||||
this thread exits. */
|
||||
int needs_unregister;
|
||||
|
||||
struct scm_thread_wake_data *wake;
|
||||
scm_i_pthread_cond_t sleep_cond;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue