[前][次][番号順一覧][スレッド一覧]

ruby-changes:19419

From: kosaki <ko1@a...>
Date: Sat, 7 May 2011 15:20:47 +0900 (JST)
Subject: [ruby-changes:19419] Ruby:r31459 (trunk): fix win32 native_cond_timedwait() makes SIGSEGV.

kosaki	2011-05-07 15:17:59 +0900 (Sat, 07 May 2011)

  New Revision: 31459

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31459

  Log:
    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.

  Modified files:
    trunk/ChangeLog
    trunk/thread_win32.c
    trunk/thread_win32.h

Index: thread_win32.c
===================================================================
--- thread_win32.c	(revision 31458)
+++ thread_win32.c	(revision 31459)
@@ -393,6 +393,7 @@
 
 struct cond_event_entry {
     struct cond_event_entry* next;
+    struct cond_event_entry* prev;
     HANDLE event;
 };
 
@@ -401,9 +402,16 @@
 {
     /* cond is guarded by mutex */
     struct cond_event_entry *e = cond->next;
+    struct cond_event_entry *head = (struct cond_event_entry*)cond;
 
-    if (e) {
-	cond->next = e->next;
+    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;
+
 	SetEvent(e->event);
     }
     else {
@@ -416,11 +424,19 @@
 {
     /* 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) {
+    while (e != head) {
+	struct cond_event_entry *next = e->next;
+	struct cond_event_entry *prev = e->prev;
+
 	SetEvent(e->event);
-	e = e->next;
+
+	prev->next = next;
+	next->prev = prev;
+	e->next = e->prev = e;
+
+	e = next;
     }
 }
 
@@ -430,19 +446,16 @@
 {
     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);
     {
@@ -453,6 +466,9 @@
     }
     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;
 }
@@ -537,8 +553,8 @@
 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
Index: thread_win32.h
===================================================================
--- thread_win32.h	(revision 31458)
+++ thread_win32.h	(revision 31459)
@@ -25,7 +25,7 @@
 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 {
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31458)
+++ ChangeLog	(revision 31459)
@@ -1,3 +1,18 @@
+Sat May  7 15:15:10 2011  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	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@g...>
 	fix mutex deadlock test hang-up.
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]