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

ruby-changes:8582

From: nobu <ko1@a...>
Date: Thu, 6 Nov 2008 22:23:07 +0900 (JST)
Subject: [ruby-changes:8582] Ruby:r20117 (trunk): * thread.c (rb_thread_stop_timer_thread): terminates timer thread

nobu	2008-11-06 22:21:26 +0900 (Thu, 06 Nov 2008)

  New Revision: 20117

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

  Log:
    * thread.c (rb_thread_stop_timer_thread): terminates timer thread
      immediately.

  Modified files:
    trunk/ChangeLog
    trunk/thread.c
    trunk/thread_pthread.c
    trunk/thread_win32.c

Index: thread_win32.c
===================================================================
--- thread_win32.c	(revision 20116)
+++ thread_win32.c	(revision 20117)
@@ -451,11 +451,26 @@
     w32_close_handle(intr);
 }
 
+static void *
+get_stack_info(const void *ptr, size_t *maxsize)
+{
+    MEMORY_BASIC_INFORMATION mi;
+    DWORD size;
+    DWORD space;
+
+    if (!VirtualQuery(ptr, &mi, sizeof(mi))) return 0;
+    size = (char *)mi.BaseAddress - (char *)mi.AllocationBase;
+    space = size / 5;
+    if (space > 1024*1024) space = 1024*1024;
+    *maxsize = size - space;
+    return (VALUE *)mi.BaseAddress - 1;
+}
+
 static unsigned long _stdcall
 thread_start_func_1(void *th_ptr)
 {
     rb_thread_t *th = th_ptr;
-    VALUE stack_start;
+    VALUE *stack_start;
     volatile HANDLE thread_id = th->thread_id;
 
     native_thread_init_stack(th);
@@ -464,8 +479,10 @@
     /* run */
     thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
 		 th->thread_id, th->native_thread_data.interrupt_event);
-    thread_start_func_2(th, &stack_start, 0);
 
+    stack_start = get_stack_info(&stack_start, &th->machine_stack_maxsize);
+    thread_start_func_2(th, stack_start, rb_ia64_bsp());
+
     w32_close_handle(thread_id);
     thread_debug("thread deleted (th: %p)\n", th);
     return 0;
@@ -531,27 +548,33 @@
 }
 
 static HANDLE timer_thread_id = 0;
+static HANDLE timer_thread_lock;
 
 static unsigned long _stdcall
 timer_thread_func(void *dummy)
 {
     thread_debug("timer_thread\n");
-    while (system_working) {
-	Sleep(WIN32_WAIT_TIMEOUT);
+    while (WaitForSingleObject(timer_thread_lock, WIN32_WAIT_TIMEOUT) ==
+	   WAIT_TIMEOUT) {
 	timer_thread_function(dummy);
     }
     thread_debug("timer killed\n");
     return 0;
 }
 
-void
+static void
 rb_thread_create_timer_thread(void)
 {
     if (timer_thread_id == 0) {
+	if (!timer_thread_lock) {
+	    timer_thread_lock = CreateEvent(0, TRUE, FALSE, 0);
+	}
 	timer_thread_id = w32_create_thread(1024 + (THREAD_DEBUG ? BUFSIZ : 0),
-					    timer_thread_func, GET_VM());
+					    timer_thread_func, 0);
 	w32_resume_thread(timer_thread_id);
     }
 }
 
+#define native_stop_timer_thread() (CloseHandle(timer_thread_lock), timer_thread_lock = 0)
+
 #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 20116)
+++ ChangeLog	(revision 20117)
@@ -1,3 +1,8 @@
+Thu Nov  6 22:21:23 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* thread.c (rb_thread_stop_timer_thread): terminates timer thread
+	  immediately.
+
 Thu Nov  6 21:21:46 2008  Masaki Suketa  <masaki.suketa@n...>
 
 	* ext/win32ole/win32ole.c (fole_s_connect, fole_initialize,
Index: thread_pthread.c
===================================================================
--- thread_pthread.c	(revision 20116)
+++ thread_pthread.c	(revision 20117)
@@ -503,6 +503,8 @@
 #define ubf_select 0
 #endif
 
+#define PER_NANO 1000000000
+
 static void
 native_sleep(rb_thread_t *th, struct timeval *tv)
 {
@@ -513,10 +515,10 @@
 	gettimeofday(&tvn, NULL);
 	ts.tv_sec = tvn.tv_sec + tv->tv_sec;
 	ts.tv_nsec = (tvn.tv_usec + tv->tv_usec) * 1000;
-        if (ts.tv_nsec >= 1000000000){
+	if (ts.tv_nsec >= PER_NANO){
 	    ts.tv_sec += 1;
-	    ts.tv_nsec -= 1000000000;
-        }
+	    ts.tv_nsec -= PER_NANO;
+	}
     }
 
     thread_debug("native_sleep %ld\n", tv ? tv->tv_sec : -1);
@@ -535,7 +537,7 @@
 		int r;
 		thread_debug("native_sleep: pthread_cond_wait start\n");
 		r = pthread_cond_wait(&th->native_thread_data.sleep_cond,
-				  &th->interrupt_lock);
+				      &th->interrupt_lock);
                 if (r) rb_bug("pthread_cond_wait: %d", r);
 		thread_debug("native_sleep: pthread_cond_wait end\n");
 	    }
@@ -651,18 +653,18 @@
 static void *
 thread_timer(void *dummy)
 {
-    while (system_working) {
 #ifdef HAVE_NANOSLEEP
-	struct timespec req, rem;
-	req.tv_sec = 0;
-	req.tv_nsec = 10 * 1000 * 1000;	/* 10 ms */
-	nanosleep(&req, &rem);
+    struct timespec req, rem;
+    req.tv_sec = 0;
+    req.tv_nsec = 10 * 1000 * 1000;	/* 10 ms */
+#define WAIT_FOR_10MS() nanosleep(&req, &rem)
 #else
-	struct timeval tv;
-	tv.tv_sec = 0;
-	tv.tv_usec = 10000;     	/* 10 ms */
-	select(0, NULL, NULL, NULL, &tv);
+    struct timeval tv;
+    tv.tv_sec = 0;
+    tv.tv_usec = 10000;     	/* 10 ms */
+#define WAIT_FOR_10MS() select(0, NULL, NULL, NULL, &tv)
 #endif
+    while (WAIT_FOR_10MS() != -1) {
 #ifndef __CYGWIN__
 	if (signal_thread_list_anchor.next) {
 	    FGLOCK(&signal_thread_list_lock, {
@@ -694,7 +696,7 @@
 	pthread_attr_setstacksize(&attr,
 				  PTHREAD_STACK_MIN + (THREAD_DEBUG ? BUFSIZ : 0));
 #endif
-	err = pthread_create(&timer_thread_id, &attr, thread_timer, GET_VM());
+	err = pthread_create(&timer_thread_id, &attr, thread_timer, 0);
 	if (err != 0) {
 	    rb_bug("rb_thread_create_timer_thread: return non-zero (%d)", err);
 	}
@@ -702,4 +704,6 @@
     rb_disable_interrupt(); /* only timer thread recieve signal */
 }
 
+#define native_stop_timer_thread() pthread_kill(timer_thread_id, SIGTERM)
+
 #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
Index: thread.c
===================================================================
--- thread.c	(revision 20116)
+++ thread.c	(revision 20117)
@@ -71,10 +71,10 @@
 
 void rb_signal_exec(rb_thread_t *th, int sig);
 void rb_disable_interrupt(void);
+void rb_thread_stop_timer_thread(void);
 
 static const VALUE eKillSignal = INT2FIX(0);
 static const VALUE eTerminateSignal = INT2FIX(1);
-static volatile int system_working = 1;
 
 inline static void
 st_delete_wrap(st_table *table, st_data_t key)
@@ -318,7 +318,7 @@
 	}
 	POP_TAG();
     }
-    system_working = 0;
+    rb_thread_stop_timer_thread();
 }
 
 static void
@@ -2322,7 +2322,7 @@
 static void
 timer_thread_function(void *arg)
 {
-    rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */
+    rb_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */
     int sig;
 
     /* for time slice */
@@ -2356,7 +2356,7 @@
 rb_thread_stop_timer_thread(void)
 {
     if (timer_thread_id) {
-	system_working = 0;
+	native_stop_timer_thread();
 	native_thread_join(timer_thread_id);
 	timer_thread_id = 0;
     }

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

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