diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-23 09:33:53 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-02-23 09:33:53 +0000 |
commit | bb022bed3a0e20b6fee92ad8910d1e0651c43f18 (patch) | |
tree | 17b2da3d61e6c55ff9a85cd8117e91bbc2dd9ccc | |
parent | bcd3345136047deb36943468bc4382074b96405f (diff) | |
download | ruby-bb022bed3a0e20b6fee92ad8910d1e0651c43f18.tar.gz |
* thread.c (rb_thread_polling): check interrupts here.
* thread_win32.ci (w32_wait_events): rename from w32_wait_event(), and
now receive multiple event handles.
* win32/win32.c (wait_events, rb_w32_main_context): removed.
* thread_win32.ci (rb_w32_wait_events): new function.
* thread_win32.ci, win32/win32.c (rb_w32_sleep, rb_w32_Sleep): move
from win32/win32.c to thread_win32.ci, and use w32_wait_events().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11832 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | thread.c | 1 | ||||
-rw-r--r-- | thread_win32.ci | 57 | ||||
-rw-r--r-- | win32/win32.c | 124 | ||||
-rw-r--r-- | win32/win32.h | 1 |
5 files changed, 61 insertions, 136 deletions
@@ -1,3 +1,17 @@ +Fri Feb 23 18:27:17 2007 NAKAMURA Usaku <usa@ruby-lang.org> + + * thread.c (rb_thread_polling): check interrupts here. + + * thread_win32.ci (w32_wait_events): rename from w32_wait_event(), and + now receive multiple event handles. + + * win32/win32.c (wait_events, rb_w32_main_context): removed. + + * thread_win32.ci (rb_w32_wait_events): new function. + + * thread_win32.ci, win32/win32.c (rb_w32_sleep, rb_w32_Sleep): move + from win32/win32.c to thread_win32.ci, and use w32_wait_events(). + Fri Feb 23 18:13:22 2007 Minero Aoki <aamine@loveruby.net> * test/ruby/test_optimization.rb: new test (merges test_opts.rb). @@ -546,6 +546,7 @@ rb_thread_wait_for(struct timeval time) void rb_thread_polling(void) { + RUBY_VM_CHECK_INTS(); if (!rb_thread_alone()) { rb_thread_t *th = GET_THREAD(); sleep_for_polling(th); diff --git a/thread_win32.ci b/thread_win32.ci index 4a681b36c3..aa1664a58a 100644 --- a/thread_win32.ci +++ b/thread_win32.ci @@ -67,17 +67,13 @@ w32_reset_event(HANDLE handle) } static int -w32_wait_event(HANDLE event, DWORD timeout, rb_thread_t *th) +w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th) { - HANDLE events[2]; - int count = 0; + HANDLE *targets = events; DWORD ret; - if (event) { - events[count++] = event; - thread_debug(" * handle: %p (count: %d)\n", event, count); - } - + thread_debug(" w32_wait_events events:%p, count:%d, timeout:%ld, th:%p\n", + events, count, timeout, th); if (th) { HANDLE intr = th->native_thread_data.interrupt_event; w32_reset_event(intr); @@ -85,12 +81,15 @@ w32_wait_event(HANDLE event, DWORD timeout, rb_thread_t *th) w32_set_event(intr); } - events[count++] = intr; + targets = ALLOCA_N(HANDLE, count + 1); + memcpy(targets, events, sizeof(HANDLE) * count); + + targets[count++] = intr; thread_debug(" * handle: %p (count: %d, intr)\n", intr, count); } thread_debug(" WaitForMultipleObjects start (count: %d)\n", count); - ret = WaitForMultipleObjects(count, events, FALSE, timeout); + ret = WaitForMultipleObjects(count, targets, FALSE, timeout); thread_debug(" WaitForMultipleObjects end (ret: %d)\n", ret); if (ret == WAIT_OBJECT_0 + count - 1 && th) { @@ -101,12 +100,24 @@ w32_wait_event(HANDLE event, DWORD timeout, rb_thread_t *th) DWORD dmy; for (i = 0; i < count; i++) { thread_debug(" * error handle %d - %s\n", i, - GetHandleInformation(events[i], &dmy) ? "OK" : "NG"); + GetHandleInformation(targets[i], &dmy) ? "OK" : "NG"); } } return ret; } +static void ubf_handle(rb_thread_t *th); +#define ubf_select ubf_handle + +int +rb_w32_wait_events(HANDLE *events, int num, DWORD timeout) +{ + int ret; + + BLOCKING_REGION(ret = w32_wait_events(events, num, timeout, GET_THREAD()), ubf_handle); + return ret; +} + static void w32_close_handle(HANDLE handle) { @@ -129,8 +140,20 @@ w32_create_thread(DWORD stack_size, void *func, void *val) return (HANDLE)_beginthreadex(0, stack_size, func, val, CREATE_SUSPENDED, 0); } -static void ubf_handle(rb_thread_t *th); -#define ubf_select ubf_handle +int +rb_w32_sleep(unsigned long msec) +{ + return w32_wait_events(0, 0, msec, GET_THREAD()); +} + +int WINAPI +rb_w32_Sleep(unsigned long msec) +{ + int ret; + + BLOCKING_REGION(ret = rb_w32_sleep(msec), ubf_handle); + return ret; +} static void native_sleep(rb_thread_t *th, struct timeval *tv) @@ -150,7 +173,7 @@ native_sleep(rb_thread_t *th, struct timeval *tv) th->status = THREAD_STOPPED; th->unblock_function = ubf_handle; thread_debug("native_sleep start (%d)\n", (int)msec); - ret = w32_wait_event(0, msec, th); + ret = w32_wait_events(0, 0, msec, th); thread_debug("native_sleep done (%d)\n", ret); th->unblock_function = 0; th->status = status; @@ -165,7 +188,7 @@ native_mutex_lock(rb_thread_lock_t *lock) DWORD result; while (1) { thread_debug("native_mutex_lock: %p\n", *lock); - result = w32_wait_event(*lock, INFINITE, 0); + result = w32_wait_events(&*lock, 1, INFINITE, 0); switch (result) { case WAIT_OBJECT_0: /* get mutex object */ @@ -212,7 +235,7 @@ native_mutex_trylock(rb_thread_lock_t *lock) #if USE_WIN32MUTEX int result; thread_debug("native_mutex_trylock: %p\n", *lock); - result = w32_wait_event(*lock, 1, 0); + result = w32_wait_events(&*lock, 1, 1, 0); thread_debug("native_mutex_trylock result: %d\n", result); switch (result) { case WAIT_OBJECT_0: @@ -306,7 +329,7 @@ native_thread_create(rb_thread_t *th) static void native_thread_join(HANDLE th) { - w32_wait_event(th, 0, 0); + w32_wait_events(&th, 1, 0, 0); } static void diff --git a/win32/win32.c b/win32/win32.c index f9816c30e5..ed7473a84b 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -82,7 +82,7 @@ static struct ChildRecord *CreateChild(const char *, const char *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE); static int has_redirection(const char *); static void StartSockets(void); -static DWORD wait_events(HANDLE event, DWORD timeout); +int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout); #if !defined(_WIN32_WCE) static int rb_w32_open_osfhandle(long osfhandle, int flags); #else @@ -231,9 +231,6 @@ static struct { DWORD id; } main_thread; -/* interrupt stuff */ -static HANDLE interrupted_event; - HANDLE GetCurrentThreadHandle(void) { @@ -2208,9 +2205,6 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, trap = *ex; else trap.fd_count = 0; - if (trap.fd_count < FD_SETSIZE) - trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event; - // else unable to catch interrupt. ex = &trap; #endif /* USE_INTERRUPT_WINSOCK */ @@ -2253,7 +2247,6 @@ rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, r = do_select(nfds, rd, wr, ex, timeout); #if USE_INTERRUPT_WINSOCK - RUBY_CRITICAL(ret = __WSAFDIsSet((SOCKET)interrupted_event, ex)); if (ret) { // In this case, we must restore all FDs. But this is only a test // code, so we think about that later. @@ -2286,9 +2279,6 @@ StartSockets(void) main_thread.handle = GetCurrentThreadHandle(); main_thread.id = GetCurrentThreadId(); - interrupted_event = CreateSignal(); - if (!interrupted_event) - rb_fatal("Unable to create interrupt event!\n"); NtSocketsInitialized = 1; } @@ -2943,7 +2933,7 @@ waitpid(rb_pid_t pid, int *stat_loc, int options) if (pid == -1) { int count = 0; DWORD ret; - HANDLE events[MAXCHILDNUM + 1]; + HANDLE events[MAXCHILDNUM]; FOREACH_CHILD(child) { if (!child->pid || child->pid < 0) continue; @@ -2954,13 +2944,10 @@ waitpid(rb_pid_t pid, int *stat_loc, int options) errno = ECHILD; return -1; } - events[count] = interrupted_event; - ret = WaitForMultipleEvents(count + 1, events, FALSE, timeout, TRUE); + ret = rb_w32_wait_events(events, count, timeout); if (ret == WAIT_TIMEOUT) return 0; if ((ret -= WAIT_OBJECT_0) == count) { - ResetSignal(interrupted_event); - errno = EINTR; return -1; } if (ret > count) { @@ -2979,7 +2966,7 @@ waitpid(rb_pid_t pid, int *stat_loc, int options) while (!(pid = poll_child_status(child, stat_loc))) { /* wait... */ - if (wait_events(child->hProcess, timeout) != WAIT_OBJECT_0) { + if (rb_w32_wait_events(&child->hProcess, 1, timeout) != WAIT_OBJECT_0) { /* still active */ pid = 0; break; @@ -3658,28 +3645,6 @@ rb_w32_times(struct tms *tmbuf) #define yield_once() Sleep(0) #define yield_until(condition) do yield_once(); while (!(condition)) -static DWORD -wait_events(HANDLE event, DWORD timeout) -{ - HANDLE events[2]; - int count = 0; - DWORD ret; - - if (event) { - events[count++] = event; - } - events[count++] = interrupted_event; - - ret = WaitForMultipleEvents(count, events, FALSE, timeout, TRUE); - - if (ret == WAIT_OBJECT_0 + count - 1) { - ResetSignal(interrupted_event); - errno = EINTR; - } - - return ret; -} - static CRITICAL_SECTION * system_state(void) { @@ -3780,88 +3745,11 @@ setup_call(CONTEXT* ctx, struct handler_arg_t *harg) #endif } -int -rb_w32_main_context(int arg, void (*handler)(int)) -{ - static HANDLE interrupt_done = NULL; - struct handler_arg_t harg; - CONTEXT ctx_orig; - HANDLE current_thread = GetCurrentThread(); - int old_priority = GetThreadPriority(current_thread); - - if (GetCurrentThreadId() == main_thread.id) return FALSE; - - SetSignal(interrupted_event); - - RUBY_CRITICAL({ /* the main thread must be in user state */ - CONTEXT ctx; - - SuspendThread(main_thread.handle); - SetThreadPriority(current_thread, GetThreadPriority(main_thread.handle)); - - ZeroMemory(&ctx, sizeof(CONTEXT)); - ctx.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT; - GetThreadContext(main_thread.handle, &ctx); - ctx_orig = ctx; - - /* handler context setup */ - if (!interrupt_done) { - interrupt_done = CreateEvent(NULL, FALSE, FALSE, NULL); - /* anonymous one-shot event */ - } - else { - ResetEvent(interrupt_done); - } - setup_call(&ctx, setup_handler(&harg, arg, handler, interrupt_done)); - - ctx.ContextFlags = CONTEXT_CONTROL; - SetThreadContext(main_thread.handle, &ctx); - ResumeThread(main_thread.handle); - }); - - /* give a chance to the main thread */ - yield_once(); - WaitForSingleObject(interrupt_done, INFINITE); /* handshaking */ - - if (!harg.status) { - /* no exceptions raised, restore old context. */ - RUBY_CRITICAL({ - /* ensure the main thread is in user state. */ - yield_until(harg.finished); - - SuspendThread(main_thread.handle); - ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT; - SetThreadContext(main_thread.handle, &ctx_orig); - ResumeThread(main_thread.handle); - }); - } - /* otherwise leave the main thread raised */ - - SetThreadPriority(current_thread, old_priority); - - return TRUE; -} - -int -rb_w32_sleep(unsigned long msec) -{ - return rb_w32_Sleep(msec); -} - -int WINAPI -rb_w32_Sleep(unsigned long msec) -{ - DWORD ret; - RUBY_CRITICAL(ret = wait_events(NULL, msec)); - yield_once(); - return ret != WAIT_TIMEOUT; -} - static void catch_interrupt(void) { yield_once(); - RUBY_CRITICAL(wait_events(NULL, 0)); + RUBY_CRITICAL(rb_w32_wait_events(NULL, 0, 0)); } #if defined __BORLANDC__ || defined _WIN32_WCE @@ -3972,7 +3860,7 @@ rb_w32_asynchronize(asynchronous_func_t func, VALUE self, if (thr) { yield_until(arg.stackaddr); - if (wait_events(thr, INFINITE) != WAIT_OBJECT_0) { + if (rb_w32_wait_events(&thr, 1, INFINITE) != WAIT_OBJECT_0) { interrupted = TRUE; if (TerminateThread(thr, intrval)) { diff --git a/win32/win32.h b/win32/win32.h index dccb63d116..8ff7db320d 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -510,7 +510,6 @@ int rb_w32_times(struct tms *); /* thread stuff */ HANDLE GetCurrentThreadHandle(void); -int rb_w32_main_context(int arg, void (*handler)(int)); int rb_w32_sleep(unsigned long msec); void rb_w32_enter_critical(void); void rb_w32_leave_critical(void); |