http://bugs.winehq.org/show_bug.cgi?id=22291
--- Comment #17 from Mike Kaplinskiy mike.kaplinskiy@gmail.com 2010-05-28 18:16:24 --- Looks like a blocked WSARecvFrom is not woken up by the socket's shutdown/close:
trace:winsock:WS_socket af=2 type=2 protocol=17 trace:winsock:WSASocketA af=2 type=2 protocol=17 protocol_info=(nil) group=0 flags=0x1 trace:winsock:WSASocketW af=2 type=2 protocol=17 protocol_info=(nil) group=0 flags=0x1 trace:winsock:WS_select read 0xfde8a0, write (nil), excp (nil) timeout 0xfde660 trace:winsock:WSASocketW created 0080 trace:winsock:WS_ioctlsocket socket 0080, cmd 8004667e, ptr 0x33e664 trace:winsock:WS_ioctlsocket socket 0080, cmd 8004667e, ptr 0x33e678 trace:winsock:WS_setsockopt socket: 0080, level 0xffff, name 0x1002, ptr 0x33e664, len 4 trace:winsock:WS_bind socket 0080, ptr 0x33e638 { family AF_INET, address 0.0.0.0, port 0 }, length 16 trace:winsock:WS_getsockname socket: 0080, ptr 0x33e638, len 10 trace:winsock:DllMain 0x7ee40000 0x2 (nil) trace:winsock:WSARecvFrom socket 0080, wsabuf 0x10de954, nbufs 1, flags 0, from 0x10de998, fromlen 16, ovl (nil), func (nil) trace:winsock:WSARecvFrom fd=47, options=0
....
trace:winsock:WS_shutdown socket 0080, how 2 0 trace:winsock:WS2_register_async_shutdown s 128 type 1 trace:winsock:WS2_register_async_shutdown s 128 type 2 trace:winsock:DllMain 0x7ee40000 0x3 (nil) trace:winsock:WSAAsyncSelect 80, hWnd (nil), uMsg 00000000, event 00000000 trace:winsock:WS_closesocket socket 0080
I have absolutely no idea how making the actual socket blocking affects shutdown behavior. This is a UDP socket though, so it might. Something like the below might help:
diff --git a/server/sock.c b/server/sock.c index b75c5a6..9aa927d 100644 --- a/server/sock.c +++ b/server/sock.c @@ -621,6 +621,7 @@ static void sock_destroy( struct object *obj ) if (sock->fd) { /* shut the socket down to force pending poll() calls in the client to return */ + fcntl(get_unix_fd(sock->fd), F_SETFL, fcntl(get_unix_fd(sock->fd), F_GETFL, 0) & ~O_NONBLOCK); shutdown( get_unix_fd(sock->fd), SHUT_RDWR ); release_object( sock->fd ); }