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

ruby-changes:65420

From: Nobuyoshi <ko1@a...>
Date: Mon, 8 Mar 2021 19:47:08 +0900 (JST)
Subject: [ruby-changes:65420] 1a00402987 (master): Enclose crtitical sections in `thread_exclusive` block

https://git.ruby-lang.org/ruby.git/commit/?id=1a00402987

From 1a00402987558db93f2741f3b500ceadd7b17dcd Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 23 Feb 2021 16:22:43 +0900
Subject: Enclose crtitical sections in `thread_exclusive` block

---
 win32/win32.c | 91 +++++++++++++++++++++++++----------------------------------
 1 file changed, 39 insertions(+), 52 deletions(-)

diff --git a/win32/win32.c b/win32/win32.c
index c97d935..027303b 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -704,6 +704,10 @@ static CRITICAL_SECTION conlist_mutex; https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L704
 static st_table *conlist = NULL;
 #define conlist_disabled ((st_table *)-1)
 
+#define thread_exclusive(obj) \
+    for (bool first = (EnterCriticalSection(&obj##_mutex), true); \
+	 first; first = (LeaveCriticalSection(&obj##_mutex), false))
+
 static char *uenvarea;
 
 /* License: Ruby's */
@@ -728,13 +732,13 @@ free_conlist(st_data_t key, st_data_t val, st_data_t arg) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L732
 static void
 constat_delete(HANDLE h)
 {
-    EnterCriticalSection(&conlist_mutex);
-    if (conlist && conlist != conlist_disabled) {
-	st_data_t key = (st_data_t)h, val;
-	st_delete(conlist, &key, &val);
-	xfree((struct constat *)val);
+    thread_exclusive(conlist) {
+	if (conlist && conlist != conlist_disabled) {
+	    st_data_t key = (st_data_t)h, val;
+	    st_delete(conlist, &key, &val);
+	    xfree((struct constat *)val);
+	}
     }
-    LeaveCriticalSection(&conlist_mutex);
 }
 
 /* License: Ruby's */
@@ -817,13 +821,13 @@ socklist_insert(SOCKET sock, int flag) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L821
 {
     int ret;
 
-    EnterCriticalSection(&socklist_mutex);
-    if (!socklist) {
-	socklist = st_init_numtable();
-	install_vm_exit_handler();
+    thread_exclusive(socklist) {
+	if (!socklist) {
+	    socklist = st_init_numtable();
+	    install_vm_exit_handler();
+	}
+	ret = st_insert(socklist, (st_data_t)sock, (st_data_t)flag);
     }
-    ret = st_insert(socklist, (st_data_t)sock, (st_data_t)flag);
-    LeaveCriticalSection(&socklist_mutex);
 
     return ret;
 }
@@ -833,18 +837,14 @@ static inline int https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L837
 socklist_lookup(SOCKET sock, int *flagp)
 {
     st_data_t data;
-    int ret;
+    int ret = 0;
 
-    EnterCriticalSection(&socklist_mutex);
-    if (socklist) {
+    thread_exclusive(socklist) {
+	if (!socklist) continue;
 	ret = st_lookup(socklist, (st_data_t)sock, (st_data_t *)&data);
 	if (ret && flagp)
 	    *flagp = (int)data;
     }
-    else {
-	ret = 0;
-    }
-    LeaveCriticalSection(&socklist_mutex);
 
     return ret;
 }
@@ -855,10 +855,10 @@ socklist_delete(SOCKET *sockp, int *flagp) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L855
 {
     st_data_t key;
     st_data_t data;
-    int ret;
+    int ret = 0;
 
-    EnterCriticalSection(&socklist_mutex);
-    if (socklist) {
+    thread_exclusive(socklist) {
+	if (!socklist) continue;
 	key = (st_data_t)*sockp;
 	if (flagp)
 	    data = (st_data_t)*flagp;
@@ -869,10 +869,6 @@ socklist_delete(SOCKET *sockp, int *flagp) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L869
 		*flagp = (int)data;
 	}
     }
-    else {
-	ret = 0;
-    }
-    LeaveCriticalSection(&socklist_mutex);
 
     return ret;
 }
@@ -2914,7 +2910,7 @@ rb_w32_fdisset(int fd, fd_set *set) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L2910
     SOCKET s = TO_SOCKET(fd);
     if (s == (SOCKET)INVALID_HANDLE_VALUE)
         return 0;
-    RUBY_CRITICAL(ret = __WSAFDIsSet(s, set));
+    RUBY_CRITICAL {ret = __WSAFDIsSet(s, set);}
     return ret;
 }
 
@@ -3118,9 +3114,9 @@ do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L3114
     }
     else {
 	RUBY_CRITICAL {
-	    EnterCriticalSection(&select_mutex);
-	    r = select(nfds, rd, wr, ex, timeout);
-	    LeaveCriticalSection(&select_mutex);
+	    thread_exclusive(select) {
+		r = select(nfds, rd, wr, ex, timeout);
+	    }
 	    if (r == SOCKET_ERROR) {
 		errno = map_errno(WSAGetLastError());
 		r = -1;
@@ -6593,19 +6589,19 @@ static struct constat * https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L6589
 constat_handle(HANDLE h)
 {
     st_data_t data;
-    struct constat *p;
-
-    EnterCriticalSection(&conlist_mutex);
-    if (!conlist) {
-	if (console_emulator_p()) {
-	    conlist = conlist_disabled;
-	}
-	else {
+    struct constat *p = NULL;
+    thread_exclusive(conlist) {
+	if (!conlist) {
+	    if (console_emulator_p()) {
+		conlist = conlist_disabled;
+		continue;
+	    }
 	    conlist = st_init_numtable();
 	    install_vm_exit_handler();
 	}
-    }
-    if (conlist != conlist_disabled) {
+	else if (conlist == conlist_disabled) {
+	    continue;
+	}
 	if (st_lookup(conlist, (st_data_t)h, &data)) {
 	    p = (struct constat *)data;
 	}
@@ -6622,11 +6618,6 @@ constat_handle(HANDLE h) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L6618
 	    st_insert(conlist, (st_data_t)h, (st_data_t)p);
 	}
     }
-    else {
-	p = NULL;
-    }
-    LeaveCriticalSection(&conlist_mutex);
-
     return p;
 }
 
@@ -6636,16 +6627,12 @@ constat_reset(HANDLE h) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L6627
 {
     st_data_t data;
     struct constat *p;
-
-    EnterCriticalSection(&conlist_mutex);
-    if (
-	conlist && conlist != conlist_disabled &&
-	st_lookup(conlist, (st_data_t)h, &data)
-    ) {
+    thread_exclusive(conlist) {
+	if (!conlist || conlist == conlist_disabled) continue;
+	if (!st_lookup(conlist, (st_data_t)h, &data)) continue;
 	p = (struct constat *)data;
 	p->vt100.state = constat_init;
     }
-    LeaveCriticalSection(&conlist_mutex);
 }
 
 #define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
-- 
cgit v1.1


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

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