mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
fix win32 native_cond_timedwait() makes SIGSEGV.
* thread_win32.h (rb_thread_cond_struct): add prev field instead of last. (ie cond_event_entry is now using double linked list instead of single) * thread_win32.c (cond_event_entry): add prev field. * thread_win32.c (__cond_timedwait): remove entry properly if timeout was happen. * thread_win32.c (native_cond_signal): change for double linked list. * thread_win32.c (native_cond_broadcast): ditto. * thread_win32.c (native_cond_initialize): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31459 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
471fb33b1a
commit
94e4d61bda
3 changed files with 48 additions and 17 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
Sat May 7 15:15:10 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
|
fix win32 native_cond_timedwait() makes SIGSEGV.
|
||||||
|
|
||||||
|
* thread_win32.h (rb_thread_cond_struct): add prev field instead of last.
|
||||||
|
(ie cond_event_entry is now using double linked list instead of single)
|
||||||
|
* thread_win32.c (cond_event_entry): add prev field.
|
||||||
|
|
||||||
|
* thread_win32.c (__cond_timedwait): remove entry properly if timeout
|
||||||
|
was happen.
|
||||||
|
|
||||||
|
* thread_win32.c (native_cond_signal): change for double linked list.
|
||||||
|
* thread_win32.c (native_cond_broadcast): ditto.
|
||||||
|
* thread_win32.c (native_cond_initialize): ditto.
|
||||||
|
|
||||||
Sat May 7 12:41:04 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Sat May 7 12:41:04 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
fix mutex deadlock test hang-up.
|
fix mutex deadlock test hang-up.
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,7 @@ native_mutex_destroy(rb_thread_lock_t *lock)
|
||||||
|
|
||||||
struct cond_event_entry {
|
struct cond_event_entry {
|
||||||
struct cond_event_entry* next;
|
struct cond_event_entry* next;
|
||||||
|
struct cond_event_entry* prev;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -401,9 +402,16 @@ native_cond_signal(rb_thread_cond_t *cond)
|
||||||
{
|
{
|
||||||
/* cond is guarded by mutex */
|
/* cond is guarded by mutex */
|
||||||
struct cond_event_entry *e = cond->next;
|
struct cond_event_entry *e = cond->next;
|
||||||
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
||||||
|
|
||||||
|
if (e != head) {
|
||||||
|
struct cond_event_entry *next = e->next;
|
||||||
|
struct cond_event_entry *prev = e->prev;
|
||||||
|
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
e->next = e->prev = e;
|
||||||
|
|
||||||
if (e) {
|
|
||||||
cond->next = e->next;
|
|
||||||
SetEvent(e->event);
|
SetEvent(e->event);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -416,11 +424,19 @@ native_cond_broadcast(rb_thread_cond_t *cond)
|
||||||
{
|
{
|
||||||
/* cond is guarded by mutex */
|
/* cond is guarded by mutex */
|
||||||
struct cond_event_entry *e = cond->next;
|
struct cond_event_entry *e = cond->next;
|
||||||
cond->next = 0;
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
||||||
|
|
||||||
|
while (e != head) {
|
||||||
|
struct cond_event_entry *next = e->next;
|
||||||
|
struct cond_event_entry *prev = e->prev;
|
||||||
|
|
||||||
while (e) {
|
|
||||||
SetEvent(e->event);
|
SetEvent(e->event);
|
||||||
e = e->next;
|
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
e->next = e->prev = e;
|
||||||
|
|
||||||
|
e = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,19 +446,16 @@ __cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, unsigned long
|
||||||
{
|
{
|
||||||
DWORD r;
|
DWORD r;
|
||||||
struct cond_event_entry entry;
|
struct cond_event_entry entry;
|
||||||
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
||||||
|
|
||||||
entry.next = 0;
|
|
||||||
entry.event = CreateEvent(0, FALSE, FALSE, 0);
|
entry.event = CreateEvent(0, FALSE, FALSE, 0);
|
||||||
|
entry.mutex = mutex;
|
||||||
|
|
||||||
/* cond is guarded by mutex */
|
/* cond is guarded by mutex */
|
||||||
if (cond->next) {
|
entry.next = head;
|
||||||
cond->last->next = &entry;
|
entry.prev = head->prev;
|
||||||
cond->last = &entry;
|
head->prev->next = &entry;
|
||||||
}
|
head->prev = &entry;
|
||||||
else {
|
|
||||||
cond->next = &entry;
|
|
||||||
cond->last = &entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
native_mutex_unlock(mutex);
|
native_mutex_unlock(mutex);
|
||||||
{
|
{
|
||||||
|
@ -453,6 +466,9 @@ __cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, unsigned long
|
||||||
}
|
}
|
||||||
native_mutex_lock(mutex);
|
native_mutex_lock(mutex);
|
||||||
|
|
||||||
|
entry.prev->next = entry.next;
|
||||||
|
entry.next->prev = entry.prev;
|
||||||
|
|
||||||
w32_close_handle(entry.event);
|
w32_close_handle(entry.event);
|
||||||
return (r == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
|
return (r == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
@ -537,8 +553,8 @@ native_cond_timeout(rb_thread_cond_t *cond, struct timespec timeout_rel)
|
||||||
static void
|
static void
|
||||||
native_cond_initialize(rb_thread_cond_t *cond, int flags)
|
native_cond_initialize(rb_thread_cond_t *cond, int flags)
|
||||||
{
|
{
|
||||||
cond->next = 0;
|
cond->next = (struct cond_event_entry *)cond;
|
||||||
cond->last = 0;
|
cond->prev = (struct cond_event_entry *)cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -25,7 +25,7 @@ typedef HANDLE rb_thread_id_t;
|
||||||
typedef CRITICAL_SECTION rb_thread_lock_t;
|
typedef CRITICAL_SECTION rb_thread_lock_t;
|
||||||
typedef struct rb_thread_cond_struct {
|
typedef struct rb_thread_cond_struct {
|
||||||
struct cond_event_entry *next;
|
struct cond_event_entry *next;
|
||||||
struct cond_event_entry *last;
|
struct cond_event_entry *prev;
|
||||||
} rb_thread_cond_t;
|
} rb_thread_cond_t;
|
||||||
|
|
||||||
typedef struct native_thread_data_struct {
|
typedef struct native_thread_data_struct {
|
||||||
|
|
Loading…
Reference in a new issue