mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +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.
|
/* Perform first stage of thread initialisation, in non-guile mode.
|
||||||
*/
|
*/
|
||||||
static void
|
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;
|
scm_i_thread t;
|
||||||
|
|
||||||
|
@ -410,6 +410,7 @@ guilify_self_1 (struct GC_stack_base *base)
|
||||||
|
|
||||||
t.exited = 0;
|
t.exited = 0;
|
||||||
t.guile_mode = 0;
|
t.guile_mode = 0;
|
||||||
|
t.needs_unregister = needs_unregister;
|
||||||
|
|
||||||
/* The switcheroo. */
|
/* The switcheroo. */
|
||||||
{
|
{
|
||||||
|
@ -523,8 +524,13 @@ on_thread_exit (void *v)
|
||||||
scm_i_vm_free_stack (vp);
|
scm_i_vm_free_stack (vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SCM_HAVE_THREAD_STORAGE_CLASS
|
||||||
|
scm_i_current_thread = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#if SCM_USE_PTHREAD_THREADS
|
||||||
GC_unregister_my_thread ();
|
if (t->needs_unregister)
|
||||||
|
GC_unregister_my_thread ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,6 +592,8 @@ scm_i_init_thread_for_guile (struct GC_stack_base *base,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int needs_unregister = 0;
|
||||||
|
|
||||||
/* Guile is already initialized, but this thread enters it for
|
/* Guile is already initialized, but this thread enters it for
|
||||||
the first time. Only initialize this thread.
|
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. */
|
/* Register this thread with libgc. */
|
||||||
#if SCM_USE_PTHREAD_THREADS
|
#if SCM_USE_PTHREAD_THREADS
|
||||||
GC_register_my_thread (base);
|
if (GC_register_my_thread (base) == GC_SUCCESS)
|
||||||
|
needs_unregister = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
guilify_self_1 (base);
|
guilify_self_1 (base, needs_unregister);
|
||||||
guilify_self_2 (dynamic_state);
|
guilify_self_2 (dynamic_state);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1782,7 +1791,7 @@ scm_threads_prehistory (void *base)
|
||||||
GC_MAKE_PROC (GC_new_proc (thread_mark), 0),
|
GC_MAKE_PROC (GC_new_proc (thread_mark), 0),
|
||||||
0, 1);
|
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;
|
scm_t_bits scm_tc16_thread;
|
||||||
|
|
|
@ -59,6 +59,9 @@ typedef struct scm_i_thread {
|
||||||
|
|
||||||
/* Boolean indicating whether the thread is in guile mode. */
|
/* Boolean indicating whether the thread is in guile mode. */
|
||||||
int 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;
|
struct scm_thread_wake_data *wake;
|
||||||
scm_i_pthread_cond_t sleep_cond;
|
scm_i_pthread_cond_t sleep_cond;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue