mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* thread.c (rb_thread_stop_timer_thread): terminates timer thread
immediately. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20117 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
514626ad8d
commit
5732566f4d
4 changed files with 56 additions and 24 deletions
|
@ -1,3 +1,8 @@
|
|||
Thu Nov 6 22:21:23 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* thread.c (rb_thread_stop_timer_thread): terminates timer thread
|
||||
immediately.
|
||||
|
||||
Thu Nov 6 21:21:46 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* ext/win32ole/win32ole.c (fole_s_connect, fole_initialize,
|
||||
|
|
8
thread.c
8
thread.c
|
@ -71,10 +71,10 @@ static void rb_check_deadlock(rb_vm_t *vm);
|
|||
|
||||
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 @@ rb_thread_terminate_all(void)
|
|||
}
|
||||
POP_TAG();
|
||||
}
|
||||
system_working = 0;
|
||||
rb_thread_stop_timer_thread();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2322,7 +2322,7 @@ int rb_get_next_signal(void);
|
|||
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 @@ void
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -503,6 +503,8 @@ ubf_select(void *ptr)
|
|||
#define ubf_select 0
|
||||
#endif
|
||||
|
||||
#define PER_NANO 1000000000
|
||||
|
||||
static void
|
||||
native_sleep(rb_thread_t *th, struct timeval *tv)
|
||||
{
|
||||
|
@ -513,10 +515,10 @@ native_sleep(rb_thread_t *th, struct timeval *tv)
|
|||
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 @@ native_sleep(rb_thread_t *th, struct timeval *tv)
|
|||
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 pthread_t timer_thread_id;
|
|||
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 @@ rb_thread_create_timer_thread(void)
|
|||
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_thread_create_timer_thread(void)
|
|||
rb_disable_interrupt(); /* only timer thread recieve signal */
|
||||
}
|
||||
|
||||
#define native_stop_timer_thread() pthread_kill(timer_thread_id, SIGTERM)
|
||||
|
||||
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
|
||||
|
|
|
@ -451,11 +451,26 @@ native_thread_destroy(rb_thread_t *th)
|
|||
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,7 +479,9 @@ thread_start_func_1(void *th_ptr)
|
|||
/* 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);
|
||||
|
@ -531,27 +548,33 @@ ubf_handle(void *ptr)
|
|||
}
|
||||
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue