[前][次][番号順一覧][スレッド一覧]

ruby-changes:12893

From: akr <ko1@a...>
Date: Sun, 23 Aug 2009 01:19:37 +0900 (JST)
Subject: [ruby-changes:12893] Ruby:r24628 (trunk): * thread.c (rb_thread_schedule): don't recur infinitely.

akr	2009-08-23 01:19:18 +0900 (Sun, 23 Aug 2009)

  New Revision: 24628

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24628

  Log:
    * thread.c (rb_thread_schedule): don't recur infinitely.
      (rb_threadptr_execute_interrupts): ditto.
      [ruby-dev:38060]

  Modified files:
    trunk/ChangeLog
    trunk/thread.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 24627)
+++ ChangeLog	(revision 24628)
@@ -1,3 +1,9 @@
+Sun Aug 23 00:56:13 2009  Tanaka Akira  <akr@f...>
+
+	* thread.c (rb_thread_schedule): don't recur infinitely.
+	  (rb_threadptr_execute_interrupts): ditto.
+	  [ruby-dev:38060]
+
 Sat Aug 22 15:07:23 2009  Tanaka Akira  <akr@f...>
 
 	* ext/syck/rubyext.c (id_hash_new): new function to create a hash
Index: thread.c
===================================================================
--- thread.c	(revision 24627)
+++ thread.c	(revision 24628)
@@ -931,8 +931,10 @@
     rb_thread_wait_for(rb_time_timeval(INT2FIX(sec)));
 }
 
-void
-rb_thread_schedule(void)
+static void rb_threadptr_execute_interrupts_rec(rb_thread_t *, int);
+
+static void
+rb_thread_schedule_rec(int sched_depth)
 {
     thread_debug("rb_thread_schedule\n");
     if (!rb_thread_alone()) {
@@ -950,10 +952,18 @@
 	rb_thread_set_current(th);
 	thread_debug("rb_thread_schedule/switch done\n");
 
-	RUBY_VM_CHECK_INTS();
+        if (!sched_depth && UNLIKELY(GET_THREAD()->interrupt_flag)) {
+            rb_threadptr_execute_interrupts_rec(GET_THREAD(), sched_depth+1);
+        }
     }
 }
 
+void
+rb_thread_schedule(void)
+{
+    rb_thread_schedule_rec(0);
+}
+
 /* blocking region */
 static inline void
 blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region,
@@ -1183,8 +1193,8 @@
  *
  */
 
-void
-rb_threadptr_execute_interrupts(rb_thread_t *th)
+static void
+rb_threadptr_execute_interrupts_rec(rb_thread_t *th, int sched_depth)
 {
     if (GET_VM()->main_thread == th) {
 	while (rb_signal_buff_size() && !th->exec_signal) native_thread_yield();
@@ -1227,7 +1237,8 @@
 	    rb_gc_finalize_deferred();
 	}
 
-	if (timer_interrupt) {
+	if (!sched_depth && timer_interrupt) {
+            sched_depth++;
 	    EXEC_EVENT_HOOK(th, RUBY_EVENT_SWITCH, th->cfp->self, 0, 0);
 
 	    if (th->slice > 0) {
@@ -1235,7 +1246,7 @@
 	    }
 	    else {
 	      reschedule:
-		rb_thread_schedule();
+		rb_thread_schedule_rec(sched_depth+1);
 		if (th->slice < 0) {
 		    th->slice++;
 		    goto reschedule;
@@ -1248,6 +1259,11 @@
     }
 }
 
+void
+rb_threadptr_execute_interrupts(rb_thread_t *th)
+{
+    rb_threadptr_execute_interrupts_rec(th, 0);
+}
 
 void
 rb_gc_mark_threads(void)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]