* thread.c (thread_cleanup_func): unlock all locked mutexes even when
forking. [ruby-core:22269] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22577 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
7019187067
commit
c55dd9b7d8
@ -1,3 +1,8 @@
|
|||||||
|
Tue Feb 24 01:19:38 2009 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
|
* thread.c (thread_cleanup_func): unlock all locked mutexes even when
|
||||||
|
forking. [ruby-core:22269]
|
||||||
|
|
||||||
Tue Feb 24 00:54:16 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Tue Feb 24 00:54:16 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* insns.def (opt_minus): inline float operation.
|
* insns.def (opt_minus): inline float operation.
|
||||||
|
@ -216,6 +216,18 @@ assert_equal 'true', %{
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal 'ok', %{
|
||||||
|
open("zzz.rb", "w") do |f|
|
||||||
|
f.puts <<-END
|
||||||
|
Thread.new { fork { GC.start } }.join
|
||||||
|
pid, status = Process.wait2
|
||||||
|
$result = status.success? ? :ok : :ng
|
||||||
|
END
|
||||||
|
end
|
||||||
|
require "zzz.rb"
|
||||||
|
$result
|
||||||
|
}
|
||||||
|
|
||||||
assert_finish 3, %{
|
assert_finish 3, %{
|
||||||
th = Thread.new {sleep 2}
|
th = Thread.new {sleep 2}
|
||||||
th.join(1)
|
th.join(1)
|
||||||
|
22
thread.c
22
thread.c
@ -291,7 +291,7 @@ typedef struct rb_mutex_struct
|
|||||||
struct rb_mutex_struct *next_mutex;
|
struct rb_mutex_struct *next_mutex;
|
||||||
} mutex_t;
|
} mutex_t;
|
||||||
|
|
||||||
static void rb_mutex_unlock_all(mutex_t *mutex);
|
static void rb_mutex_unlock_all(mutex_t *mutex, rb_thread_t *th);
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_thread_terminate_all(void)
|
rb_thread_terminate_all(void)
|
||||||
@ -305,7 +305,7 @@ rb_thread_terminate_all(void)
|
|||||||
|
|
||||||
/* unlock all locking mutexes */
|
/* unlock all locking mutexes */
|
||||||
if (th->keeping_mutexes) {
|
if (th->keeping_mutexes) {
|
||||||
rb_mutex_unlock_all(th->keeping_mutexes);
|
rb_mutex_unlock_all(th->keeping_mutexes, GET_THREAD());
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
|
||||||
@ -339,6 +339,12 @@ static void
|
|||||||
thread_cleanup_func(void *th_ptr)
|
thread_cleanup_func(void *th_ptr)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = th_ptr;
|
rb_thread_t *th = th_ptr;
|
||||||
|
|
||||||
|
/* unlock all locking mutexes */
|
||||||
|
if (th->keeping_mutexes) {
|
||||||
|
rb_mutex_unlock_all(th->keeping_mutexes, th);
|
||||||
|
th->keeping_mutexes = NULL;
|
||||||
|
}
|
||||||
thread_cleanup_func_before_exec(th_ptr);
|
thread_cleanup_func_before_exec(th_ptr);
|
||||||
native_thread_destroy(th);
|
native_thread_destroy(th);
|
||||||
}
|
}
|
||||||
@ -434,12 +440,6 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||||||
(void *)th, th->locking_mutex);
|
(void *)th, th->locking_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlock all locking mutexes */
|
|
||||||
if (th->keeping_mutexes) {
|
|
||||||
rb_mutex_unlock_all(th->keeping_mutexes);
|
|
||||||
th->keeping_mutexes = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete self other than main thread from living_threads */
|
/* delete self other than main thread from living_threads */
|
||||||
if (th != main_th) {
|
if (th != main_th) {
|
||||||
st_delete_wrap(th->vm->living_threads, th->self);
|
st_delete_wrap(th->vm->living_threads, th->self);
|
||||||
@ -457,7 +457,6 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||||||
}
|
}
|
||||||
join_th = join_th->join_list_next;
|
join_th = join_th->join_list_next;
|
||||||
}
|
}
|
||||||
if (th != main_th) rb_check_deadlock(th->vm);
|
|
||||||
|
|
||||||
if (!th->root_fiber) {
|
if (!th->root_fiber) {
|
||||||
rb_thread_recycle_stack_release(th->stack);
|
rb_thread_recycle_stack_release(th->stack);
|
||||||
@ -465,6 +464,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread_cleanup_func(th);
|
thread_cleanup_func(th);
|
||||||
|
if (th != main_th) rb_check_deadlock(th->vm);
|
||||||
if (th->vm->main_thread == th) {
|
if (th->vm->main_thread == th) {
|
||||||
ruby_cleanup(state);
|
ruby_cleanup(state);
|
||||||
}
|
}
|
||||||
@ -3146,7 +3146,7 @@ rb_mutex_unlock(VALUE self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_mutex_unlock_all(mutex_t *mutexes)
|
rb_mutex_unlock_all(mutex_t *mutexes, rb_thread_t *th)
|
||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
mutex_t *mutex;
|
mutex_t *mutex;
|
||||||
@ -3156,7 +3156,7 @@ rb_mutex_unlock_all(mutex_t *mutexes)
|
|||||||
/* rb_warn("mutex #<%p> remains to be locked by terminated thread",
|
/* rb_warn("mutex #<%p> remains to be locked by terminated thread",
|
||||||
mutexes); */
|
mutexes); */
|
||||||
mutexes = mutex->next_mutex;
|
mutexes = mutex->next_mutex;
|
||||||
err = mutex_unlock(mutex, GET_THREAD());
|
err = mutex_unlock(mutex, th);
|
||||||
if (err) rb_bug("invalid keeping_mutexes: %s", err);
|
if (err) rb_bug("invalid keeping_mutexes: %s", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user