diff options
author | Neil Jerram <neil@ossau.uklinux.net> | 2008-02-07 01:24:31 +0000 |
---|---|---|
committer | Neil Jerram <neil@ossau.uklinux.net> | 2008-02-07 01:24:31 +0000 |
commit | 86a597f8b38ecc9de563977aa150ddff3771cadc (patch) | |
tree | f9bf7c8dc3fb7559f26c6221f448620b8e3934e3 /libguile | |
parent | 0ea659f3ba4067425c4779da03e2e76e9b0651ca (diff) | |
download | guile-86a597f8b38ecc9de563977aa150ddff3771cadc.tar.gz |
* threads.c (do_thread_exit, scm_cancel_thread,
scm_set_thread_cleanup_x, scm_thread_cleanup): Lock on thread-specific
admin mutex instead of `thread_admin_mutex'.
* threads.h (scm_i_thread)[admin_mutex]: New field.
* throw.c (make_jmpbuf): Don't enter critical section during thread
spawn -- there is a possibility of deadlock if other threads are
exiting.
Diffstat (limited to 'libguile')
-rw-r--r-- | libguile/ChangeLog | 10 | ||||
-rw-r--r-- | libguile/threads.c | 35 | ||||
-rw-r--r-- | libguile/threads.h | 5 | ||||
-rw-r--r-- | libguile/throw.c | 12 |
4 files changed, 36 insertions, 26 deletions
diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 69a95e772..ce60ca4dc 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,13 @@ +2008-02-07 Julian Graham <joolean@gmail.com> + + * threads.c (do_thread_exit, scm_cancel_thread, + scm_set_thread_cleanup_x, scm_thread_cleanup): Lock on thread-specific + admin mutex instead of `thread_admin_mutex'. + * threads.h (scm_i_thread)[admin_mutex]: New field. + * throw.c (make_jmpbuf): Don't enter critical section during thread + spawn -- there is a possibility of deadlock if other threads are + exiting. + 2008-02-06 Neil Jerram <neil@ossau.uklinux.net> * gc-malloc.c (scm_gc_malloc): Return NULL if requested size is 0. diff --git a/libguile/threads.c b/libguile/threads.c index 524884dd4..ba0aa1a55 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -435,6 +435,7 @@ guilify_self_1 (SCM_STACKITEM *base) /* XXX - check for errors. */ pipe (t->sleep_pipe); scm_i_pthread_mutex_init (&t->heap_mutex, NULL); + scm_i_pthread_mutex_init (&t->admin_mutex, NULL); t->clear_freelists_p = 0; t->gc_running_p = 0; t->canceled = 0; @@ -494,7 +495,7 @@ do_thread_exit (void *v) scm_handle_by_message_noexit, NULL); } - scm_i_scm_pthread_mutex_lock (&thread_admin_mutex); + scm_i_scm_pthread_mutex_lock (&t->admin_mutex); t->exited = 1; close (t->sleep_pipe[0]); @@ -502,7 +503,7 @@ do_thread_exit (void *v) while (scm_is_true (unblock_from_queue (t->join_queue))) ; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); return NULL; } @@ -931,15 +932,15 @@ SCM_DEFINE (scm_cancel_thread, "cancel-thread", 1, 0, 0, SCM_VALIDATE_THREAD (1, thread); t = SCM_I_THREAD_DATA (thread); - scm_i_scm_pthread_mutex_lock (&thread_admin_mutex); + scm_i_scm_pthread_mutex_lock (&t->admin_mutex); if (!t->canceled) { t->canceled = 1; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); scm_i_pthread_cancel (t->pthread); } else - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); return SCM_UNSPECIFIED; } @@ -957,13 +958,13 @@ SCM_DEFINE (scm_set_thread_cleanup_x, "set-thread-cleanup!", 2, 0, 0, if (!scm_is_false (proc)) SCM_VALIDATE_THUNK (2, proc); - scm_i_pthread_mutex_lock (&thread_admin_mutex); - t = SCM_I_THREAD_DATA (thread); + scm_i_pthread_mutex_lock (&t->admin_mutex); + if (!(t->exited || t->canceled)) t->cleanup_handler = proc; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); return SCM_UNSPECIFIED; } @@ -979,10 +980,10 @@ SCM_DEFINE (scm_thread_cleanup, "thread-cleanup", 1, 0, 0, SCM_VALIDATE_THREAD (1, thread); - scm_i_pthread_mutex_lock (&thread_admin_mutex); t = SCM_I_THREAD_DATA (thread); + scm_i_pthread_mutex_lock (&t->admin_mutex); ret = (t->exited || t->canceled) ? SCM_BOOL_F : t->cleanup_handler; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); return ret; } @@ -1001,24 +1002,24 @@ SCM_DEFINE (scm_join_thread, "join-thread", 1, 0, 0, if (scm_is_eq (scm_current_thread (), thread)) SCM_MISC_ERROR ("cannot join the current thread", SCM_EOL); - scm_i_scm_pthread_mutex_lock (&thread_admin_mutex); - t = SCM_I_THREAD_DATA (thread); + scm_i_scm_pthread_mutex_lock (&t->admin_mutex); + if (!t->exited) { while (1) { - block_self (t->join_queue, thread, &thread_admin_mutex, NULL); + block_self (t->join_queue, thread, &t->admin_mutex, NULL); if (t->exited) break; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); SCM_TICK; - scm_i_scm_pthread_mutex_lock (&thread_admin_mutex); + scm_i_scm_pthread_mutex_lock (&t->admin_mutex); } } res = t->result; - scm_i_pthread_mutex_unlock (&thread_admin_mutex); + scm_i_pthread_mutex_unlock (&t->admin_mutex); return res; } diff --git a/libguile/threads.h b/libguile/threads.h index 47dfe108f..b19fbe3f4 100644 --- a/libguile/threads.h +++ b/libguile/threads.h @@ -3,7 +3,7 @@ #ifndef SCM_THREADS_H #define SCM_THREADS_H -/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1996,1997,1998,2000,2001, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,6 +52,9 @@ typedef struct scm_i_thread { SCM cleanup_handler; SCM join_queue; + + scm_i_pthread_mutex_t admin_mutex; + SCM result; int canceled; int exited; diff --git a/libguile/throw.c b/libguile/throw.c index 02503c36a..55d83d41a 100644 --- a/libguile/throw.c +++ b/libguile/throw.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997,1998,2000,2001, 2003, 2004, 2006, 2008 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -75,13 +75,9 @@ static SCM make_jmpbuf (void) { SCM answer; - SCM_CRITICAL_SECTION_START; - { - SCM_NEWSMOB2 (answer, tc16_jmpbuffer, 0, 0); - SETJBJMPBUF(answer, (jmp_buf *)0); - DEACTIVATEJB(answer); - } - SCM_CRITICAL_SECTION_END; + SCM_NEWSMOB2 (answer, tc16_jmpbuffer, 0, 0); + SETJBJMPBUF(answer, (jmp_buf *)0); + DEACTIVATEJB(answer); return answer; } |