mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
* 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.
This commit is contained in:
parent
0ea659f3ba
commit
86a597f8b3
5 changed files with 37 additions and 26 deletions
1
NEWS
1
NEWS
|
@ -54,6 +54,7 @@ system and library calls.
|
||||||
** Fixed compilation of `numbers.c' with Sun Studio (Solaris 9)
|
** Fixed compilation of `numbers.c' with Sun Studio (Solaris 9)
|
||||||
** Fixed wrong-type-arg errors when creating zero length SRFI-4
|
** Fixed wrong-type-arg errors when creating zero length SRFI-4
|
||||||
uniform vectors on AIX.
|
uniform vectors on AIX.
|
||||||
|
** Fixed a deadlock that occurs upon GC with multiple threads.
|
||||||
|
|
||||||
* New modules (see the manual for details)
|
* New modules (see the manual for details)
|
||||||
|
|
||||||
|
|
|
@ -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>
|
2008-02-06 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
* gc-malloc.c (scm_gc_malloc): Return NULL if requested size is 0.
|
* gc-malloc.c (scm_gc_malloc): Return NULL if requested size is 0.
|
||||||
|
|
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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. */
|
/* XXX - check for errors. */
|
||||||
pipe (t->sleep_pipe);
|
pipe (t->sleep_pipe);
|
||||||
scm_i_pthread_mutex_init (&t->heap_mutex, NULL);
|
scm_i_pthread_mutex_init (&t->heap_mutex, NULL);
|
||||||
|
scm_i_pthread_mutex_init (&t->admin_mutex, NULL);
|
||||||
t->clear_freelists_p = 0;
|
t->clear_freelists_p = 0;
|
||||||
t->gc_running_p = 0;
|
t->gc_running_p = 0;
|
||||||
t->canceled = 0;
|
t->canceled = 0;
|
||||||
|
@ -494,7 +495,7 @@ do_thread_exit (void *v)
|
||||||
scm_handle_by_message_noexit, NULL);
|
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;
|
t->exited = 1;
|
||||||
close (t->sleep_pipe[0]);
|
close (t->sleep_pipe[0]);
|
||||||
|
@ -502,7 +503,7 @@ do_thread_exit (void *v)
|
||||||
while (scm_is_true (unblock_from_queue (t->join_queue)))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -931,15 +932,15 @@ SCM_DEFINE (scm_cancel_thread, "cancel-thread", 1, 0, 0,
|
||||||
|
|
||||||
SCM_VALIDATE_THREAD (1, thread);
|
SCM_VALIDATE_THREAD (1, thread);
|
||||||
t = SCM_I_THREAD_DATA (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)
|
if (!t->canceled)
|
||||||
{
|
{
|
||||||
t->canceled = 1;
|
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);
|
scm_i_pthread_cancel (t->pthread);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||||
|
|
||||||
return SCM_UNSPECIFIED;
|
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))
|
if (!scm_is_false (proc))
|
||||||
SCM_VALIDATE_THUNK (2, proc);
|
SCM_VALIDATE_THUNK (2, proc);
|
||||||
|
|
||||||
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
|
||||||
|
|
||||||
t = SCM_I_THREAD_DATA (thread);
|
t = SCM_I_THREAD_DATA (thread);
|
||||||
|
scm_i_pthread_mutex_lock (&t->admin_mutex);
|
||||||
|
|
||||||
if (!(t->exited || t->canceled))
|
if (!(t->exited || t->canceled))
|
||||||
t->cleanup_handler = proc;
|
t->cleanup_handler = proc;
|
||||||
|
|
||||||
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||||
|
|
||||||
return SCM_UNSPECIFIED;
|
return SCM_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
@ -979,10 +980,10 @@ SCM_DEFINE (scm_thread_cleanup, "thread-cleanup", 1, 0, 0,
|
||||||
|
|
||||||
SCM_VALIDATE_THREAD (1, thread);
|
SCM_VALIDATE_THREAD (1, thread);
|
||||||
|
|
||||||
scm_i_pthread_mutex_lock (&thread_admin_mutex);
|
|
||||||
t = SCM_I_THREAD_DATA (thread);
|
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;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1001,24 +1002,24 @@ SCM_DEFINE (scm_join_thread, "join-thread", 1, 0, 0,
|
||||||
if (scm_is_eq (scm_current_thread (), thread))
|
if (scm_is_eq (scm_current_thread (), thread))
|
||||||
SCM_MISC_ERROR ("cannot join the current thread", SCM_EOL);
|
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);
|
t = SCM_I_THREAD_DATA (thread);
|
||||||
|
scm_i_scm_pthread_mutex_lock (&t->admin_mutex);
|
||||||
|
|
||||||
if (!t->exited)
|
if (!t->exited)
|
||||||
{
|
{
|
||||||
while (1)
|
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)
|
if (t->exited)
|
||||||
break;
|
break;
|
||||||
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||||
SCM_TICK;
|
SCM_TICK;
|
||||||
scm_i_scm_pthread_mutex_lock (&thread_admin_mutex);
|
scm_i_scm_pthread_mutex_lock (&t->admin_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = t->result;
|
res = t->result;
|
||||||
|
|
||||||
scm_i_pthread_mutex_unlock (&thread_admin_mutex);
|
scm_i_pthread_mutex_unlock (&t->admin_mutex);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#ifndef SCM_THREADS_H
|
#ifndef SCM_THREADS_H
|
||||||
#define 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -52,6 +52,9 @@ typedef struct scm_i_thread {
|
||||||
|
|
||||||
SCM cleanup_handler;
|
SCM cleanup_handler;
|
||||||
SCM join_queue;
|
SCM join_queue;
|
||||||
|
|
||||||
|
scm_i_pthread_mutex_t admin_mutex;
|
||||||
|
|
||||||
SCM result;
|
SCM result;
|
||||||
int canceled;
|
int canceled;
|
||||||
int exited;
|
int exited;
|
||||||
|
|
|
@ -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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -75,13 +75,9 @@ static SCM
|
||||||
make_jmpbuf (void)
|
make_jmpbuf (void)
|
||||||
{
|
{
|
||||||
SCM answer;
|
SCM answer;
|
||||||
SCM_CRITICAL_SECTION_START;
|
SCM_NEWSMOB2 (answer, tc16_jmpbuffer, 0, 0);
|
||||||
{
|
SETJBJMPBUF(answer, (jmp_buf *)0);
|
||||||
SCM_NEWSMOB2 (answer, tc16_jmpbuffer, 0, 0);
|
DEACTIVATEJB(answer);
|
||||||
SETJBJMPBUF(answer, (jmp_buf *)0);
|
|
||||||
DEACTIVATEJB(answer);
|
|
||||||
}
|
|
||||||
SCM_CRITICAL_SECTION_END;
|
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue