From 402c8cf9d1f67e326f41dc003f3d9ca6924810ec Mon Sep 17 00:00:00 2001 From: usa Date: Thu, 20 Oct 2011 13:55:31 +0000 Subject: [PATCH] * win32/win32.c (socklist_insert, socklist_lookup, socklist_delete): new functions to wrap of st_insert(), st_lookup() and st_delete() to socklist. allocating socklist is deferred until it is really needed. * win32/win32.c (exit_handler): delete socklist only if it is initialized. * win32/win32.c (rb_w32_sysinit, StartSockets): refactoring: move initialization of select_mutex to StartSockets(). * win32/win32.c (exit_handler): refactoring: delete select_mutex only if winsock is used. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33496 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 16 ++++++++ win32/win32.c | 100 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 84 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index d00c57ce36..069f12a009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Thu Oct 20 22:47:28 2011 NAKAMURA Usaku + + * win32/win32.c (socklist_insert, socklist_lookup, socklist_delete): + new functions to wrap of st_insert(), st_lookup() and st_delete() to + socklist. + allocating socklist is deferred until it is really needed. + + * win32/win32.c (exit_handler): delete socklist only if it is + initialized. + + * win32/win32.c (rb_w32_sysinit, StartSockets): refactoring: move + initialization of select_mutex to StartSockets(). + + * win32/win32.c (exit_handler): refactoring: delete select_mutex only + if winsock is used. + Thu Oct 20 22:38:53 2011 Martin Bosslet * ext/openssl/ossl_pkcs5.c: add note on timing attacks and general diff --git a/win32/win32.c b/win32/win32.c index 73f9b64ada..6b201764f1 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -654,15 +654,17 @@ exit_handler(void) { if (NtSocketsInitialized) { WSACleanup(); - st_free_table(socklist); - socklist = NULL; + if (socklist) { + st_free_table(socklist); + socklist = NULL; + } + DeleteCriticalSection(&select_mutex); NtSocketsInitialized = 0; } if (envarea) { FreeEnvironmentStrings(envarea); envarea = NULL; } - DeleteCriticalSection(&select_mutex); } /* License: Artistic or GPL */ @@ -682,11 +684,59 @@ StartSockets(void) if (LOBYTE(retdata.wVersion) != 2) rb_fatal("could not find version 2 of winsock dll\n"); - socklist = st_init_numtable(); + InitializeCriticalSection(&select_mutex); NtSocketsInitialized = 1; } +/* License: Ruby's */ +static inline int +socklist_insert(SOCKET sock, int flag) +{ + if (!socklist) + socklist = st_init_numtable(); + return st_insert(socklist, (st_data_t)sock, (st_data_t)flag); +} + +/* License: Ruby's */ +static inline int +socklist_lookup(SOCKET sock, int *flagp) +{ + st_data_t data; + int ret; + + if (!socklist) + return 0; + ret = st_lookup(socklist, (st_data_t)sock, (st_data_t *)&data); + if (ret && flagp) + *flagp = (int)data; + + return ret; +} + +/* License: Ruby's */ +static inline int +socklist_delete(SOCKET *sockp, int *flagp) +{ + st_data_t key; + st_data_t data; + int ret; + + if (!socklist) + return 0; + key = (st_data_t)*sockp; + if (flagp) + data = (st_data_t)*flagp; + ret = st_delete(socklist, &key, &data); + if (ret) { + *sockp = (SOCKET)key; + if (flagp) + *flagp = (int)data; + } + + return ret; +} + // // Initialization stuff // @@ -722,8 +772,6 @@ rb_w32_sysinit(int *argc, char ***argv) init_stdhandle(); - InitializeCriticalSection(&select_mutex); - atexit(exit_handler); // Initialize Winsock @@ -2270,7 +2318,7 @@ rb_w32_open_osfhandle(intptr_t osfhandle, int flags) static int is_socket(SOCKET sock) { - if (st_lookup(socklist, (st_data_t)sock, NULL)) + if (socklist_lookup(sock, NULL)) return TRUE; else return FALSE; @@ -2665,6 +2713,9 @@ do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, rb_w32_sleep(INFINITE); } else { + if (!NtSocketsInitialized) + StartSockets(); + RUBY_CRITICAL( EnterCriticalSection(&select_mutex); r = select(nfds, rd, wr, ex, timeout); @@ -2757,10 +2808,6 @@ rb_w32_select_with_thread(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, } } - if (!NtSocketsInitialized) { - StartSockets(); - } - // assume else_{rd,wr} (other than socket, pipe reader, console reader) // are always readable/writable. but this implementation still has // problem. if pipe's buffer is full, writing to pipe will block @@ -2904,7 +2951,7 @@ rb_w32_accept(int s, struct sockaddr *addr, int *addrlen) _set_osfhnd(fd, r); MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); CloseHandle(h); - st_insert(socklist, (st_data_t)r, (st_data_t)0); + socklist_insert(r, 0); } else { errno = map_errno(WSAGetLastError()); @@ -3101,7 +3148,6 @@ overlapped_socket_io(BOOL input, int fd, char *buf, int len, int flags, int r; int ret; int mode; - st_data_t data; DWORD flg; WSAOVERLAPPED wol; WSABUF wbuf; @@ -3111,8 +3157,7 @@ overlapped_socket_io(BOOL input, int fd, char *buf, int len, int flags, StartSockets(); s = TO_SOCKET(fd); - st_lookup(socklist, (st_data_t)s, &data); - mode = (int)data; + socklist_lookup(s, &mode); if (!cancel_io || (mode & O_NONBLOCK)) { RUBY_CRITICAL({ if (input) { @@ -3237,7 +3282,6 @@ recvmsg(int fd, struct msghdr *msg, int flags) static WSARecvMsg_t pWSARecvMsg = NULL; WSAMSG wsamsg; SOCKET s; - st_data_t data; int mode; DWORD len; int ret; @@ -3257,8 +3301,7 @@ recvmsg(int fd, struct msghdr *msg, int flags) msghdr_to_wsamsg(msg, &wsamsg); wsamsg.dwFlags |= flags; - st_lookup(socklist, (st_data_t)s, &data); - mode = (int)data; + socklist_lookup(s, &mode); if (!cancel_io || (mode & O_NONBLOCK)) { RUBY_CRITICAL({ if ((ret = pWSARecvMsg(s, &wsamsg, &len, NULL, NULL)) == SOCKET_ERROR) { @@ -3297,7 +3340,6 @@ sendmsg(int fd, const struct msghdr *msg, int flags) static WSASendMsg_t pWSASendMsg = NULL; WSAMSG wsamsg; SOCKET s; - st_data_t data; int mode; DWORD len; int ret; @@ -3316,8 +3358,7 @@ sendmsg(int fd, const struct msghdr *msg, int flags) msghdr_to_wsamsg(msg, &wsamsg); - st_lookup(socklist, (st_data_t)s, &data); - mode = (int)data; + socklist_lookup(s, &mode); if (!cancel_io || (mode & O_NONBLOCK)) { RUBY_CRITICAL({ if ((ret = pWSASendMsg(s, &wsamsg, flags, &len, NULL, NULL)) == SOCKET_ERROR) { @@ -3446,7 +3487,7 @@ rb_w32_socket(int af, int type, int protocol) else { fd = rb_w32_open_osfhandle(s, O_RDWR|O_BINARY|O_NOINHERIT); if (fd != -1) - st_insert(socklist, (st_data_t)s, (st_data_t)0); + socklist_insert(s, 0); else closesocket(s); } @@ -3691,8 +3732,8 @@ rb_w32_socketpair(int af, int type, int protocol, int *sv) closesocket(pair[1]); return -1; } - st_insert(socklist, (st_data_t)pair[0], (st_data_t)0); - st_insert(socklist, (st_data_t)pair[1], (st_data_t)0); + socklist_insert(pair[0], 0); + socklist_insert(pair[1], 0); return 0; } @@ -3733,7 +3774,6 @@ fcntl(int fd, int cmd, ...) int arg; int ret; int flag = 0; - st_data_t data; u_long ioctlArg; if (!is_socket(sock)) { @@ -3748,8 +3788,7 @@ fcntl(int fd, int cmd, ...) va_start(va, cmd); arg = va_arg(va, int); va_end(va); - st_lookup(socklist, (st_data_t)sock, &data); - flag = (int)data; + socklist_lookup(sock, &flag); if (arg & O_NONBLOCK) { flag |= O_NONBLOCK; ioctlArg = 1; @@ -3761,7 +3800,7 @@ fcntl(int fd, int cmd, ...) RUBY_CRITICAL({ ret = ioctlsocket(sock, FIONBIO, &ioctlArg); if (ret == 0) - st_insert(socklist, (st_data_t)sock, (st_data_t)flag); + socklist_insert(sock, flag); else errno = map_errno(WSAGetLastError()); }); @@ -5323,16 +5362,13 @@ rb_w32_close(int fd) { SOCKET sock = TO_SOCKET(fd); int save_errno = errno; - st_data_t key; if (!is_socket(sock)) { UnlockFile((HANDLE)sock, 0, 0, LK_LEN, LK_LEN); return _close(fd); } _set_osfhnd(fd, (SOCKET)INVALID_HANDLE_VALUE); - key = (st_data_t)sock; - st_delete(socklist, &key, NULL); - sock = (SOCKET)key; + socklist_delete(&sock, NULL); _close(fd); errno = save_errno; if (closesocket(sock) == SOCKET_ERROR) {