diff options
Diffstat (limited to 'thread_win32.ci')
-rw-r--r-- | thread_win32.ci | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/thread_win32.ci b/thread_win32.ci index 3bdb2e4276..46adc01028 100644 --- a/thread_win32.ci +++ b/thread_win32.ci @@ -122,7 +122,7 @@ w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th) return ret; } -static void ubf_handle(rb_thread_t *th); +static void ubf_handle(rb_thread_t *th, void *ptr); #define ubf_select ubf_handle int @@ -136,7 +136,7 @@ rb_w32_wait_events(HANDLE *events, int num, DWORD timeout) { int ret; - BLOCKING_REGION(ret = rb_w32_wait_events_blocking(events, num, timeout), ubf_handle); + BLOCKING_REGION(ret = rb_w32_wait_events_blocking(events, num, timeout), ubf_handle, 0); return ret; } @@ -187,7 +187,7 @@ rb_w32_Sleep(unsigned long msec) { int ret; - BLOCKING_REGION(ret = rb_w32_sleep(msec), ubf_handle); + BLOCKING_REGION(ret = rb_w32_sleep(msec), ubf_handle, 0); return ret; } @@ -309,6 +309,87 @@ native_mutex_destroy(rb_thread_lock_t *lock) #endif } +struct cond_event_entry { + struct cond_event_entry* next; + HANDLE event; +}; + +struct rb_thread_cond_struct { + struct cond_event_entry *next; + struct cond_event_entry *last; +}; + +void +native_cond_signal(rb_thread_cond_t *cond) +{ + /* cond is guarded by mutex */ + struct cond_event_entry *e = cond->next; + + if (e) { + cond->next = e->next; + SetEvent(e->event); + } + else { + rb_bug("native_cond_signal: no pending threads"); + } +} + +void +native_cond_broadcast(rb_thread_cond_t *cond) +{ + /* cond is guarded by mutex */ + struct cond_event_entry *e = cond->next; + cond->next = 0; + + while (e) { + SetEvent(e->event); + e = e->next; + } +} + +void +native_cond_wait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex) +{ + DWORD r; + struct cond_event_entry entry; + + entry.next = 0; + entry.event = CreateEvent(0, FALSE, FALSE, 0); + + /* cond is guarded by mutex */ + if (cond->next) { + cond->last->next = &entry; + cond->last = &entry; + } + else { + cond->next = &entry; + cond->last = &entry; + } + + native_mutex_unlock(mutex); + { + r = WaitForSingleObject(entry.event, INFINITE); + if (r != WAIT_OBJECT_0) { + rb_bug("native_cond_wait: WaitForSingleObject returns %d", r); + } + } + native_mutex_lock(mutex); + + w32_close_handle(entry.event); +} + +void +native_cond_initialize(rb_thread_cond_t *cond) +{ + cond->next = 0; + cond->last = 0; +} + +void +native_cond_destroy(rb_thread_cond_t *cond) +{ + /* */ +} static void native_thread_destroy(rb_thread_t *th) @@ -384,7 +465,7 @@ native_thread_apply_priority(rb_thread_t *th) } static void -ubf_handle(rb_thread_t *th) +ubf_handle(rb_thread_t *th, void *ptr) { thread_debug("ubf_handle: %p\n", th); w32_set_event(th->native_thread_data.interrupt_event); |