added mutexes for socket and connection lists on win32
This commit is contained in:
parent
09c74a1702
commit
0d76636117
Notes:
git
2021-02-23 16:20:28 +09:00
@ -115,4 +115,29 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
|||||||
assert_raise(IO::WaitReadable) { svr.accept_nonblock(exception: true) }
|
assert_raise(IO::WaitReadable) { svr.accept_nonblock(exception: true) }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_accept_multithread
|
||||||
|
attempts_count = 5
|
||||||
|
server_threads_count = 3
|
||||||
|
client_threads_count = 3
|
||||||
|
|
||||||
|
attempts_count.times do
|
||||||
|
server_threads = Array.new(server_threads_count) do
|
||||||
|
Thread.new do
|
||||||
|
TCPServer.open("localhost", 0) do |server|
|
||||||
|
accept_threads = Array.new(client_threads_count) do
|
||||||
|
Thread.new { server.accept.close }
|
||||||
|
end
|
||||||
|
client_threads = Array.new(client_threads_count) do
|
||||||
|
Thread.new { TCPSocket.open(server.addr[3], server.addr[1]) }
|
||||||
|
end
|
||||||
|
client_threads.each(&:join)
|
||||||
|
accept_threads.each(&:join)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
server_threads.each(&:join)
|
||||||
|
end
|
||||||
|
end
|
||||||
end if defined?(TCPSocket)
|
end if defined?(TCPSocket)
|
||||||
|
@ -696,9 +696,14 @@ rtc_error_handler(int e, const char *src, int line, const char *exe, const char
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CRITICAL_SECTION select_mutex;
|
static CRITICAL_SECTION select_mutex;
|
||||||
|
|
||||||
|
static CRITICAL_SECTION socklist_mutex;
|
||||||
static st_table *socklist = NULL;
|
static st_table *socklist = NULL;
|
||||||
|
|
||||||
|
static CRITICAL_SECTION conlist_mutex;
|
||||||
static st_table *conlist = NULL;
|
static st_table *conlist = NULL;
|
||||||
#define conlist_disabled ((st_table *)-1)
|
#define conlist_disabled ((st_table *)-1)
|
||||||
|
|
||||||
static char *uenvarea;
|
static char *uenvarea;
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -723,11 +728,13 @@ free_conlist(st_data_t key, st_data_t val, st_data_t arg)
|
|||||||
static void
|
static void
|
||||||
constat_delete(HANDLE h)
|
constat_delete(HANDLE h)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&conlist_mutex);
|
||||||
if (conlist && conlist != conlist_disabled) {
|
if (conlist && conlist != conlist_disabled) {
|
||||||
st_data_t key = (st_data_t)h, val;
|
st_data_t key = (st_data_t)h, val;
|
||||||
st_delete(conlist, &key, &val);
|
st_delete(conlist, &key, &val);
|
||||||
xfree((struct constat *)val);
|
xfree((struct constat *)val);
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&conlist_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -736,6 +743,8 @@ exit_handler(void)
|
|||||||
{
|
{
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
DeleteCriticalSection(&select_mutex);
|
DeleteCriticalSection(&select_mutex);
|
||||||
|
DeleteCriticalSection(&socklist_mutex);
|
||||||
|
DeleteCriticalSection(&conlist_mutex);
|
||||||
if (uenvarea) {
|
if (uenvarea) {
|
||||||
free(uenvarea);
|
free(uenvarea);
|
||||||
uenvarea = NULL;
|
uenvarea = NULL;
|
||||||
@ -746,15 +755,20 @@ exit_handler(void)
|
|||||||
static void
|
static void
|
||||||
vm_exit_handler(ruby_vm_t *vm)
|
vm_exit_handler(ruby_vm_t *vm)
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection(&socklist_mutex);
|
||||||
if (socklist) {
|
if (socklist) {
|
||||||
st_free_table(socklist);
|
st_free_table(socklist);
|
||||||
socklist = NULL;
|
socklist = NULL;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&socklist_mutex);
|
||||||
|
|
||||||
|
EnterCriticalSection(&conlist_mutex);
|
||||||
if (conlist && conlist != conlist_disabled) {
|
if (conlist && conlist != conlist_disabled) {
|
||||||
st_foreach(conlist, free_conlist, 0);
|
st_foreach(conlist, free_conlist, 0);
|
||||||
st_free_table(conlist);
|
st_free_table(conlist);
|
||||||
conlist = NULL;
|
conlist = NULL;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&conlist_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -787,6 +801,8 @@ StartSockets(void)
|
|||||||
rb_fatal("could not find version 2 of winsock dll");
|
rb_fatal("could not find version 2 of winsock dll");
|
||||||
|
|
||||||
InitializeCriticalSection(&select_mutex);
|
InitializeCriticalSection(&select_mutex);
|
||||||
|
InitializeCriticalSection(&socklist_mutex);
|
||||||
|
InitializeCriticalSection(&conlist_mutex);
|
||||||
|
|
||||||
atexit(exit_handler);
|
atexit(exit_handler);
|
||||||
}
|
}
|
||||||
@ -799,11 +815,17 @@ StartSockets(void)
|
|||||||
static inline int
|
static inline int
|
||||||
socklist_insert(SOCKET sock, int flag)
|
socklist_insert(SOCKET sock, int flag)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
EnterCriticalSection(&socklist_mutex);
|
||||||
if (!socklist) {
|
if (!socklist) {
|
||||||
socklist = st_init_numtable();
|
socklist = st_init_numtable();
|
||||||
install_vm_exit_handler();
|
install_vm_exit_handler();
|
||||||
}
|
}
|
||||||
return 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
@ -813,11 +835,15 @@ socklist_lookup(SOCKET sock, int *flagp)
|
|||||||
st_data_t data;
|
st_data_t data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!socklist)
|
EnterCriticalSection(&socklist_mutex);
|
||||||
return 0;
|
if (socklist) {
|
||||||
ret = st_lookup(socklist, (st_data_t)sock, (st_data_t *)&data);
|
ret = st_lookup(socklist, (st_data_t)sock, (st_data_t *)&data);
|
||||||
if (ret && flagp)
|
if (ret && flagp)
|
||||||
*flagp = (int)data;
|
*flagp = (int)data;
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&socklist_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -830,8 +856,8 @@ socklist_delete(SOCKET *sockp, int *flagp)
|
|||||||
st_data_t data;
|
st_data_t data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!socklist)
|
EnterCriticalSection(&socklist_mutex);
|
||||||
return 0;
|
if (socklist) {
|
||||||
key = (st_data_t)*sockp;
|
key = (st_data_t)*sockp;
|
||||||
if (flagp)
|
if (flagp)
|
||||||
data = (st_data_t)*flagp;
|
data = (st_data_t)*flagp;
|
||||||
@ -841,6 +867,10 @@ socklist_delete(SOCKET *sockp, int *flagp)
|
|||||||
if (flagp)
|
if (flagp)
|
||||||
*flagp = (int)data;
|
*flagp = (int)data;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&socklist_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -6562,21 +6592,20 @@ constat_handle(HANDLE h)
|
|||||||
{
|
{
|
||||||
st_data_t data;
|
st_data_t data;
|
||||||
struct constat *p;
|
struct constat *p;
|
||||||
|
|
||||||
|
EnterCriticalSection(&conlist_mutex);
|
||||||
if (!conlist) {
|
if (!conlist) {
|
||||||
if (console_emulator_p()) {
|
if (console_emulator_p()) {
|
||||||
conlist = conlist_disabled;
|
conlist = conlist_disabled;
|
||||||
return NULL;
|
} else {
|
||||||
}
|
|
||||||
conlist = st_init_numtable();
|
conlist = st_init_numtable();
|
||||||
install_vm_exit_handler();
|
install_vm_exit_handler();
|
||||||
}
|
}
|
||||||
else if (conlist == conlist_disabled) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
if (conlist != conlist_disabled) {
|
||||||
if (st_lookup(conlist, (st_data_t)h, &data)) {
|
if (st_lookup(conlist, (st_data_t)h, &data)) {
|
||||||
p = (struct constat *)data;
|
p = (struct constat *)data;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
p = ALLOC(struct constat);
|
p = ALLOC(struct constat);
|
||||||
p->vt100.state = constat_init;
|
p->vt100.state = constat_init;
|
||||||
@ -6588,6 +6617,11 @@ constat_handle(HANDLE h)
|
|||||||
}
|
}
|
||||||
st_insert(conlist, (st_data_t)h, (st_data_t)p);
|
st_insert(conlist, (st_data_t)h, (st_data_t)p);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&conlist_mutex);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6597,11 +6631,17 @@ constat_reset(HANDLE h)
|
|||||||
{
|
{
|
||||||
st_data_t data;
|
st_data_t data;
|
||||||
struct constat *p;
|
struct constat *p;
|
||||||
if (!conlist || conlist == conlist_disabled) return;
|
|
||||||
if (!st_lookup(conlist, (st_data_t)h, &data)) return;
|
EnterCriticalSection(&conlist_mutex);
|
||||||
|
if (
|
||||||
|
conlist && conlist != conlist_disabled &&
|
||||||
|
st_lookup(conlist, (st_data_t)h, &data)
|
||||||
|
) {
|
||||||
p = (struct constat *)data;
|
p = (struct constat *)data;
|
||||||
p->vt100.state = constat_init;
|
p->vt100.state = constat_init;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&conlist_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
|
#define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
|
||||||
#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
|
#define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user