Skip to content

Commit

Permalink
fix win32 native_cond_timedwait() makes SIGSEGV.
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
kosaki committed May 7, 2011
1 parent 471fb33 commit 94e4d61
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
15 changes: 15 additions & 0 deletions 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>
fix mutex deadlock test hang-up.

Expand Down
48 changes: 32 additions & 16 deletions thread_win32.c
Expand Up @@ -393,6 +393,7 @@ native_mutex_destroy(rb_thread_lock_t *lock)

struct cond_event_entry {
struct cond_event_entry* next;
struct cond_event_entry* prev;
HANDLE event;
};

Expand All @@ -401,9 +402,16 @@ native_cond_signal(rb_thread_cond_t *cond)
{
/* cond is guarded by mutex */
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);
}
else {
Expand All @@ -416,11 +424,19 @@ native_cond_broadcast(rb_thread_cond_t *cond)
{
/* cond is guarded by mutex */
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);
e = e->next;

prev->next = next;
next->prev = prev;
e->next = e->prev = e;

e = next;
}
}

Expand All @@ -430,19 +446,16 @@ __cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, unsigned long
{
DWORD r;
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.mutex = mutex;

/* cond is guarded by mutex */
if (cond->next) {
cond->last->next = &entry;
cond->last = &entry;
}
else {
cond->next = &entry;
cond->last = &entry;
}
entry.next = head;
entry.prev = head->prev;
head->prev->next = &entry;
head->prev = &entry;

native_mutex_unlock(mutex);
{
Expand All @@ -453,6 +466,9 @@ __cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, unsigned long
}
native_mutex_lock(mutex);

entry.prev->next = entry.next;
entry.next->prev = entry.prev;

w32_close_handle(entry.event);
return (r == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
}
Expand Down Expand Up @@ -537,8 +553,8 @@ native_cond_timeout(rb_thread_cond_t *cond, struct timespec timeout_rel)
static void
native_cond_initialize(rb_thread_cond_t *cond, int flags)
{
cond->next = 0;
cond->last = 0;
cond->next = (struct cond_event_entry *)cond;
cond->prev = (struct cond_event_entry *)cond;
}

static void
Expand Down
2 changes: 1 addition & 1 deletion thread_win32.h
Expand Up @@ -25,7 +25,7 @@ typedef HANDLE rb_thread_id_t;
typedef CRITICAL_SECTION rb_thread_lock_t;
typedef struct rb_thread_cond_struct {
struct cond_event_entry *next;
struct cond_event_entry *last;
struct cond_event_entry *prev;
} rb_thread_cond_t;

typedef struct native_thread_data_struct {
Expand Down

0 comments on commit 94e4d61

Please sign in to comment.