1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-06 15:40:29 +02:00

* threads.c (really_launch): Release heap (to prevent deadlock).

(create_thread): Release heap before locking thread admin mutex.
This commit is contained in:
Mikael Djurfeldt 2002-12-10 16:51:14 +00:00
parent b0dc3d710a
commit c4c52ebe30
2 changed files with 28 additions and 10 deletions

View file

@ -1,3 +1,8 @@
2002-12-10 Mikael Djurfeldt <mdj@kvast.blakulla.net>
* threads.c (really_launch): Release heap (to prevent deadlock).
(create_thread): Release heap before locking thread admin mutex.
2002-12-10 Mikael Djurfeldt <mdj@kvast.blakulla.net> 2002-12-10 Mikael Djurfeldt <mdj@kvast.blakulla.net>
* threads.c (scm_i_thread_invalidate_freelists): New * threads.c (scm_i_thread_invalidate_freelists): New

View file

@ -341,15 +341,16 @@ really_launch (SCM_STACKITEM *base, launch_data *data)
data, data,
(scm_t_catch_handler) handler_bootstrip, (scm_t_catch_handler) handler_bootstrip,
data, base); data, base);
scm_i_plugin_mutex_unlock (&t->heap_mutex); /* release the heap */
free (data); free (data);
scm_thread_detach (t->thread);
scm_i_plugin_mutex_lock (&thread_admin_mutex); scm_i_plugin_mutex_lock (&thread_admin_mutex);
all_threads = scm_delq_x (thread, all_threads); all_threads = scm_delq_x (thread, all_threads);
t->exited = 1; t->exited = 1;
thread_count--; thread_count--;
scm_i_plugin_mutex_unlock (&thread_admin_mutex); scm_i_plugin_mutex_unlock (&thread_admin_mutex);
/* We're leaving with heap_mutex still locked. */ /* We're leaving with heap_mutex still locked. */
scm_thread_detach (t->thread);
} }
static void * static void *
@ -374,7 +375,7 @@ create_thread (scm_t_catch_body body, void *body_data,
{ {
scm_t_thread th; scm_t_thread th;
SCM root, old_winds, new_threads; SCM root, old_winds;
launch_data *data; launch_data *data;
scm_thread *t; scm_thread *t;
int err; int err;
@ -402,12 +403,16 @@ create_thread (scm_t_catch_body body, void *body_data,
/* In order to avoid the need of synchronization between parent /* In order to avoid the need of synchronization between parent
and child thread, we need to insert the child into all_threads and child thread, we need to insert the child into all_threads
before creation. */ before creation. */
new_threads = scm_cons (thread, SCM_BOOL_F); /* could cause GC */ {
SCM new_threads = scm_cons (thread, SCM_BOOL_F); /* could cause GC */
scm_thread *parent = scm_i_leave_guile (); /* to prevent deadlock */
scm_i_plugin_mutex_lock (&thread_admin_mutex); scm_i_plugin_mutex_lock (&thread_admin_mutex);
SCM_SETCDR (new_threads, all_threads); SCM_SETCDR (new_threads, all_threads);
all_threads = new_threads; all_threads = new_threads;
thread_count++; thread_count++;
scm_i_plugin_mutex_unlock (&thread_admin_mutex); scm_i_plugin_mutex_unlock (&thread_admin_mutex);
scm_i_enter_guile (parent);
}
err = scm_i_plugin_thread_create (&th, 0, launch_thread, (void *) data); err = scm_i_plugin_thread_create (&th, 0, launch_thread, (void *) data);
if (err != 0) if (err != 0)
@ -1169,7 +1174,9 @@ scm_i_thread_put_to_sleep ()
SCM_REC_CRITICAL_SECTION_START (gc_section); SCM_REC_CRITICAL_SECTION_START (gc_section);
if (threads_initialized_p && gc_section_count == 1) if (threads_initialized_p && gc_section_count == 1)
{ {
SCM threads = all_threads; SCM threads;
scm_i_plugin_mutex_lock (&thread_admin_mutex);
threads = all_threads;
/* Signal all threads to go to sleep */ /* Signal all threads to go to sleep */
scm_i_thread_go_to_sleep = 1; scm_i_thread_go_to_sleep = 1;
for (; !SCM_NULLP (threads); threads = SCM_CDR (threads)) for (; !SCM_NULLP (threads); threads = SCM_CDR (threads))
@ -1179,12 +1186,14 @@ scm_i_thread_put_to_sleep ()
scm_i_plugin_mutex_lock (&t->heap_mutex); scm_i_plugin_mutex_lock (&t->heap_mutex);
} }
scm_i_thread_go_to_sleep = 0; scm_i_thread_go_to_sleep = 0;
scm_i_plugin_mutex_unlock (&thread_admin_mutex);
} }
} }
void void
scm_i_thread_invalidate_freelists () scm_i_thread_invalidate_freelists ()
{ {
/* Don't need to lock thread_admin_mutex here since we are sinle threaded */
SCM threads = all_threads; SCM threads = all_threads;
for (; !SCM_NULLP (threads); threads = SCM_CDR (threads)) for (; !SCM_NULLP (threads); threads = SCM_CDR (threads))
if (SCM_CAR (threads) != cur_thread) if (SCM_CAR (threads) != cur_thread)
@ -1199,7 +1208,10 @@ scm_i_thread_wake_up ()
{ {
if (threads_initialized_p && gc_section_count == 1) if (threads_initialized_p && gc_section_count == 1)
{ {
SCM threads = all_threads; SCM threads;
/* Need to lock since woken threads can die and be deleted from list */
scm_i_plugin_mutex_lock (&thread_admin_mutex);
threads = all_threads;
scm_i_plugin_cond_broadcast (&wake_up_cond); scm_i_plugin_cond_broadcast (&wake_up_cond);
for (; !SCM_NULLP (threads); threads = SCM_CDR (threads)) for (; !SCM_NULLP (threads); threads = SCM_CDR (threads))
if (SCM_CAR (threads) != cur_thread) if (SCM_CAR (threads) != cur_thread)
@ -1207,6 +1219,7 @@ scm_i_thread_wake_up ()
scm_thread *t = SCM_THREAD_DATA (SCM_CAR (threads)); scm_thread *t = SCM_THREAD_DATA (SCM_CAR (threads));
scm_i_plugin_mutex_unlock (&t->heap_mutex); scm_i_plugin_mutex_unlock (&t->heap_mutex);
} }
scm_i_plugin_mutex_unlock (&thread_admin_mutex);
} }
SCM_REC_CRITICAL_SECTION_END (gc_section); SCM_REC_CRITICAL_SECTION_END (gc_section);
} }