Commit dfdfba26 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ws2_32: Make wait in select() alertable.

parent a4966b66
...@@ -551,6 +551,14 @@ static HANDLE get_sync_event(void) ...@@ -551,6 +551,14 @@ static HANDLE get_sync_event(void)
return data->sync_event; return data->sync_event;
} }
static DWORD wait_event_alertable( HANDLE event )
{
DWORD ret;
while ((ret = WaitForSingleObjectEx( event, INFINITE, TRUE )) == WAIT_IO_COMPLETION)
;
return ret;
}
BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved ) BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
{ {
...@@ -2769,7 +2777,7 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr, ...@@ -2769,7 +2777,7 @@ int WINAPI select( int count, fd_set *read_ptr, fd_set *write_ptr,
IOCTL_AFD_POLL, params, params_size, params, params_size ); IOCTL_AFD_POLL, params, params_size, params, params_size );
if (status == STATUS_PENDING) if (status == STATUS_PENDING)
{ {
if (WaitForSingleObject( sync_event, INFINITE ) == WAIT_FAILED) if (wait_event_alertable( sync_event ) == WAIT_FAILED)
{ {
free( read_input ); free( read_input );
free( params ); free( params );
......
...@@ -202,6 +202,11 @@ static void tcp_socketpair(SOCKET *src, SOCKET *dst) ...@@ -202,6 +202,11 @@ static void tcp_socketpair(SOCKET *src, SOCKET *dst)
tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED); tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED);
} }
static void WINAPI apc_func(ULONG_PTR apc_count)
{
++*(unsigned int *)apc_count;
}
/* Set the linger timeout to zero and close the socket. This will trigger an /* Set the linger timeout to zero and close the socket. This will trigger an
* RST on the connection on Windows as well as on Unix systems. */ * RST on the connection on Windows as well as on Unix systems. */
static void close_with_rst(SOCKET s) static void close_with_rst(SOCKET s)
...@@ -3613,6 +3618,7 @@ static void test_select(void) ...@@ -3613,6 +3618,7 @@ static void test_select(void)
select_thread_params thread_params; select_thread_params thread_params;
HANDLE thread_handle; HANDLE thread_handle;
DWORD ticks, id, old_protect; DWORD ticks, id, old_protect;
unsigned int apc_count;
unsigned int maxfd, i; unsigned int maxfd, i;
char *page_pair; char *page_pair;
...@@ -3716,14 +3722,24 @@ static void test_select(void) ...@@ -3716,14 +3722,24 @@ static void test_select(void)
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(fdRead, &readfds); FD_SET(fdRead, &readfds);
apc_count = 0;
ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count);
ok(ret, "QueueUserAPC returned %d\n", ret);
ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout); ret = select(fdRead+1, &readfds, NULL, NULL, &select_timeout);
ok(!ret, "select returned %d\n", ret); ok(!ret, "select returned %d\n", ret);
ok(apc_count == 1, "got apc_count %d.\n", apc_count);
FD_ZERO(&writefds); FD_ZERO(&writefds);
FD_SET(fdWrite, &writefds); FD_SET(fdWrite, &writefds);
apc_count = 0;
ret = QueueUserAPC(apc_func, GetCurrentThread(), (ULONG_PTR)&apc_count);
ok(ret, "QueueUserAPC returned %d\n", ret);
ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout); ret = select(fdWrite+1, NULL, &writefds, NULL, &select_timeout);
ok(ret == 1, "select returned %d\n", ret); ok(ret == 1, "select returned %d\n", ret);
ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n"); ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
ok(!apc_count, "APC was called\n");
SleepEx(0, TRUE);
ok(apc_count == 1, "got apc_count %d.\n", apc_count);
/* select the same socket twice */ /* select the same socket twice */
writefds.fd_count = 2; writefds.fd_count = 2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment