THREAD_TO_KILL $B$r>C$9M}M3$H$+$r5-O?$K;D$7$FD:$/$HNI$+$C$?$+$H!%(B
$B$=$b$=$b(B THREAD_TO_KILL
$B$,$&$^$/[email protected]}$7$?$<!$$C$F46$8(B
$B$G$7$g$&$+!%(B
-------- Original Message --------
Subject: [ruby-changes:25874] kosaki:r37931 (trunk): * vm_core.h (enum
rb_thread_status): remove THREAD_TO_KILL
Date: Wed, 28 Nov 2012 17:31:12 +0900 (JST)
From: kosaki [email protected]
Reply-To: [email protected]
To: [email protected]
kosaki 2012-11-28 17:31:03 +0900 (Wed, 28 Nov 2012)
New Revision: 37931
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37931
Log:
* vm_core.h (enum rb_thread_status): remove THREAD_TO_KILL
* vm_core.h (struct rb_thread_struct): add to_kill field
* thread.c (terminate_i): convert THREAD_TO_KILL to to_kill.
* thread.c (rb_threadptr_to_kill): ditto.
* thread.c (rb_thread_kill): ditto.
* thread.c (rb_thread_wakeup_alive): ditto.
* thread.c (thread_list_i): ditto.
* thread.c (static const char): ditto.
* thread.c (thread_status_name): ditto.
* thread.c (rb_thread_status): ditto.
* thread.c (rb_thread_inspect): ditto.
* vm_backtrace.c (thread_backtrace_to_ary): ditto.
* thread.c (rb_threadptr_execute_interrupts): fix thread status
overwritten issue. [Bug #7450] [ruby-core:50249]
* test/ruby/test_thread.rb (test_hread_status_raise_after_kill):
test for the above.
* test/ruby/test_thread.rb (test_thread_status_in_trap): test for
thread status in trap.
* test/ruby/test_thread.rb (test_status_and_stop_p): remove
Thread.control_interrupt unsafe test. Thread#kill no longer
changes thread status. Instead of, Thread#kill receiver changes
their own status when receiving kill signal.
Modified files:
trunk/ChangeLog
trunk/test/ruby/test_thread.rb
trunk/thread.c
trunk/vm_backtrace.c
trunk/vm_core.h
Index: ChangeLog
— ChangeLog (revision 37930)
+++ ChangeLog (revision 37931)
@@ -1,3 +1,30 @@
+Wed Nov 28 16:40:14 2012 KOSAKI Motohiro [email protected]
+
-
- vm_core.h (enum rb_thread_status): remove THREAD_TO_KILL
-
- vm_core.h (struct rb_thread_struct): add to_kill field
-
- thread.c (terminate_i): convert THREAD_TO_KILL to to_kill.
-
- thread.c (rb_threadptr_to_kill): ditto.
-
- thread.c (rb_thread_kill): ditto.
-
- thread.c (rb_thread_wakeup_alive): ditto.
-
- thread.c (thread_list_i): ditto.
-
- thread.c (static const char): ditto.
-
- thread.c (thread_status_name): ditto.
-
- thread.c (rb_thread_status): ditto.
-
- thread.c (rb_thread_inspect): ditto.
-
- vm_backtrace.c (thread_backtrace_to_ary): ditto.
-
- thread.c (rb_threadptr_execute_interrupts): fix thread status
- overwritten issue. [Bug #7450] [ruby-core:50249]
-
- test/ruby/test_thread.rb (test_hread_status_raise_after_kill):
- test for the above.
-
- test/ruby/test_thread.rb (test_thread_status_in_trap): test for
- thread status in trap.
-
- test/ruby/test_thread.rb (test_status_and_stop_p): remove
- Thread.control_interrupt unsafe test. Thread#kill no longer
- changes thread status. Instead of, Thread#kill receiver changes
- their own status when receiving kill signal.
Wed Nov 28 16:21:46 2012 KOSAKI Motohiro [email protected]
- thread.c (struct rb_mutex_struct): add allow_trap field.
Index: vm_core.h
===================================================================
— vm_core.h (revision 37930)
+++ vm_core.h (revision 37931)
@@ -425,7 +425,6 @@
TypedData_Get_Struct((obj), rb_thread_t, &ruby_threadptr_data_type,
(ptr))
enum rb_thread_status {
- THREAD_TO_KILL,
THREAD_RUNNABLE,
THREAD_STOPPED,
THREAD_STOPPED_FOREVER,
@@ -498,6 +497,7 @@
/* thread control */
rb_thread_id_t thread_id;
enum rb_thread_status status;
-
int to_kill;
int priority;native_thread_data_t native_thread_data;
Index: thread.c
===================================================================
— thread.c (revision 37930)
+++ thread.c (revision 37931)
@@ -326,7 +326,6 @@
if (th != main_thread) {
thread_debug(“terminate_i: %p\n”, (void *)th);
rb_threadptr_async_errinfo_enque(th, eTerminateSignal);
- th->status = THREAD_TO_KILL;
rb_threadptr_interrupt(th);
}
else {
@@ -1732,7 +1731,8 @@
rb_threadptr_to_kill(rb_thread_t *th)
{
rb_threadptr_async_errinfo_clear(th); - th->status = THREAD_TO_KILL;
-
th->status = THREAD_RUNNABLE;
-
th->to_kill = 1;
th->errinfo = INT2FIX(TAG_FATAL);
TH_JUMP_TAG(th, TAG_FATAL);
}
@@ -1743,7 +1743,6 @@
if (th->raised_flag) return;while (1) {
-
enum rb_thread_status status = th->status;
rb_atomic_t interrupt;
rb_atomic_t old;
int sig;
@@ -1766,13 +1765,16 @@
finalizer_interrupt = interrupt & FINALIZER_INTERRUPT_MASK;
trap_interrupt = interrupt & TRAP_INTERRUPT_MASK; -
th->status = THREAD_RUNNABLE;
-
/* signal handling */
if (trap_interrupt && (th == th->vm->main_thread)) { -
enum rb_thread_status prev_status = th->status;
-
th->status = THREAD_RUNNABLE; while ((sig = rb_get_next_signal()) != 0) {
rb_signal_exec(th, sig);
} -
th->status = prev_status;
}
/* exception from another thread */
@@ -1788,10 +1790,13 @@
rb_threadptr_to_kill(th);
}
else { -
/* set runnable if th was slept. */
-
if (th->status == THREAD_STOPPED ||
-
th->status == THREAD_STOPPED_FOREVER)
-
th->status = THREAD_RUNNABLE;
rb_exc_raise(err);
}
}
-
th->status = status;
if (finalizer_interrupt) {
rb_gc_finalize_deferred();
@@ -1805,7 +1810,7 @@
else
limits_us >>= -th->priority; -
if (status == THREAD_RUNNABLE || status == THREAD_TO_KILL)
-
if (th->status == THREAD_RUNNABLE)
th->running_time_us += TIME_QUANTUM_USEC;
EXEC_EVENT_HOOK(th, RUBY_EVENT_SWITCH, th->cfp->self, 0, 0,
Qundef);
@@ -1985,7 +1990,7 @@
if (th != GET_THREAD() && th->safe_level < 4) {
rb_secure(4);
}
- if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED) {
- if (th->to_kill || th->status == THREAD_KILLED) {
return thread;
}
if (th == th->vm->main_thread) {
@@ -2000,7 +2005,6 @@
}
else {
rb_threadptr_async_errinfo_enque(th, eKillSignal);
- th->status = THREAD_TO_KILL;
rb_threadptr_interrupt(th);
}
return thread;
@@ -2082,9 +2086,8 @@
return Qnil;
}
rb_threadptr_ready(th); - if (th->status != THREAD_TO_KILL) {
- if (th->status == THREAD_STOPPED || th->status ==
THREAD_STOPPED_FOREVER)
th->status = THREAD_RUNNABLE;
- }
return thread;
}
@@ -2157,7 +2160,6 @@
case THREAD_RUNNABLE:
case THREAD_STOPPED:
case THREAD_STOPPED_FOREVER:
-
rb_ary_push(ary, th->self);case THREAD_TO_KILL:
default:
break;
@@ -2352,16 +2354,17 @@
}
static const char *
-thread_status_name(enum rb_thread_status status)
+thread_status_name(rb_thread_t *th)
{
- switch (status) {
- switch (th->status) {
case THREAD_RUNNABLE:
- return “run”;
- if (th->to_kill)
-
return "aborting";
- else
-
return “sleep”;return "run"; case THREAD_STOPPED: case THREAD_STOPPED_FOREVER:
-
case THREAD_TO_KILL:
- return “aborting”;
case THREAD_KILLED:
return “dead”;
default:
@@ -2411,7 +2414,7 @@
}
return Qfalse;
} - return rb_str_new2(thread_status_name(th->status));
- return rb_str_new2(thread_status_name(th));
}
@@ -2500,7 +2503,7 @@
VALUE str;
GetThreadPtr(thread, th);
- status = thread_status_name(th->status);
- status = thread_status_name(th);
str = rb_sprintf("#<%s:%p %s>", cname, (void *)thread, status);
OBJ_INFECT(str, thread);
Index: vm_backtrace.c
— vm_backtrace.c (revision 37930)
+++ vm_backtrace.c (revision 37931)
@@ -738,15 +738,8 @@
rb_thread_t *th;
GetThreadPtr(thval, th);
- switch (th->status) {
-
case THREAD_RUNNABLE:
-
case THREAD_STOPPED:
-
case THREAD_STOPPED_FOREVER:
- break;
-
case THREAD_TO_KILL:
-
case THREAD_KILLED:
- if (th->to_kill || th->status == THREAD_KILLED)
return Qnil;
-
}
return vm_backtrace_to_ary(th, argc, argv, 0, 0, to_str);
}
Index: test/ruby/test_thread.rb
===================================================================
— test/ruby/test_thread.rb (revision 37930)
+++ test/ruby/test_thread.rb (revision 37931)
@@ -497,7 +497,6 @@
a = ::Thread.new { raise(“die now”) }
b = Thread.new { Thread.stop }
c = Thread.new { Thread.exit } -
d = Thread.new { sleep }
e = Thread.current
sleep 0.5
@@ -511,21 +510,14 @@
assert_match(/^#<TestThread:.* dead>$/, c.inspect)
assert(c.stop?)
-
d.kill
-
to avoid thread switching…
-
ds1 = d.status
-
ds2 = d.stop?
es1 = e.status
es2 = e.stop? -
assert_equal([“aborting”, false], [ds1, ds2])
-
assert_equal([“run”, false], [es1, es2])
ensure
a.kill if a
b.kill if b
c.kill if c -
d.kill if d
end
def test_safe_level
@@ -912,4 +904,47 @@
}
INPUT
end
+
- def test_thread_status_in_trap
-
when running trap handler, Thread#status must show “run”
-
Even though interrupted from sleeping function
- assert_in_out_err([], <<-INPUT, %w(sleep run), [])
-
Signal.trap(:INT) {
-
puts Thread.current.status
-
}
-
Thread.new(Thread.current) {|mth|
-
sleep 0.01
-
puts mth.status
-
Process.kill(:INT, $$)
-
}
-
sleep 0.1
- INPUT
- end
-
Bug #7450
- def test_thread_status_raise_after_kill
- ary = []
- t = Thread.new {
-
begin
-
ary << Thread.current.status
-
sleep
-
ensure
-
begin
-
ary << Thread.current.status
-
sleep
-
ensure
-
ary << Thread.current.status
-
end
-
end
- }
- sleep 0.01
- t.kill
- sleep 0.01
- t.raise
- sleep 0.01
- assert_equal(ary, [“run”, “aborting”, “aborting”])
- end
end