Thanks, sorry about that; forgot to pull. Here's an updated version.
And the compile warning is harmless.

Also - small question: there is a for loop so that the test doesn't
run forever should it fail. What would be a good replacement for that?
(the way its set up is: select is 10ms*4000=40secs max)

Mike.

On Sat, Jul 11, 2009 at 5:47 PM, Paul Vriens<paul.vriens.w...@gmail.com> wrote:
> Mike Kaplinskiy wrote:
>>
>> Can someone try this test on win2000+? This tests the
>> WSAAccept->Defer->AcceptEx scenario, and I've only verified the
>> behavior on xp.
>>
>> Thanks,
>> Mike
>>
>>
>> ------------------------------------------------------------------------
>>
>>
> Hi Mike,
>
> No failures on W2K3 SP2.
>
> Patch doesn't apply cleanly and there is compile warning:
>
> sock.c:2781: warning: passing argument 5 of 'WSAAccept' makes integer from
> pointer without a cast
>
> --
> Cheers,
>
> Paul.
>
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index acb2638..4e9627a 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -2539,17 +2539,26 @@ static void test_GetAddrInfoW(void)
     pFreeAddrInfoW(result);
 }
 
+static int CALLBACK AlwaysDeferConditionFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS pQos,
+                                             LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData,
+                                             GROUP FAR * g, DWORD_PTR dwCallbackData)
+{
+    return CF_DEFER;
+}
+
 static void test_AcceptEx(void)
 {
     SOCKET listener = INVALID_SOCKET;
     SOCKET acceptor = INVALID_SOCKET;
     SOCKET connector = INVALID_SOCKET;
+    SOCKET connector2 = INVALID_SOCKET;
     struct sockaddr_in bindAddress;
     int socklen;
     GUID acceptExGuid = WSAID_ACCEPTEX;
-    BOOL WINAPI (*pAcceptEx)(SOCKET listener, SOCKET acceptor, PVOID dest, DWORD dest_len,
-        DWORD local_addr_len, DWORD rem_addr_len, LPDWORD received,
-        LPOVERLAPPED overlapped);
+    LPFN_ACCEPTEX pAcceptEx = NULL;
+    fd_set fds_accept, fds_send;
+    struct timeval timeout = {0,10}; /* wait for 10 milliseconds */
+    int got, conn1, i;
     DWORD bytesReturned;
     char buffer[1024];
     OVERLAPPED overlapped;
@@ -2711,6 +2720,116 @@ static void test_AcceptEx(void)
     bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
     ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
     ok(bytesReturned == 1, "bytesReturned isn't supposed to be %d\n", bytesReturned);
+    
+    closesocket(connector);
+    connector = INVALID_SOCKET;
+    closesocket(acceptor);
+    acceptor = INVALID_SOCKET;
+    
+    /* Test CF_DEFER & AcceptEx interaction */
+    
+    acceptor = socket(AF_INET, SOCK_STREAM, 0);
+    if (acceptor == INVALID_SOCKET) {
+        skip("could not create acceptor socket, error %d\n", WSAGetLastError());
+        goto end;
+    }
+    connector = socket(AF_INET, SOCK_STREAM, 0);
+    if (connector == INVALID_SOCKET) {
+        skip("could not create connector socket, error %d\n", WSAGetLastError());
+        goto end;
+    }
+    connector2 = socket(AF_INET, SOCK_STREAM, 0);
+    if (connector == INVALID_SOCKET) {
+        skip("could not create connector socket, error %d\n", WSAGetLastError());
+        goto end;
+    }
+    
+    if (set_blocking(connector, FALSE)) {
+        skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
+        goto end;
+    }
+    
+    if (set_blocking(connector2, FALSE)) {
+        skip("couldn't make socket non-blocking, error %d\n", WSAGetLastError());
+        goto end;
+    }
+    
+    /* Connect socket #1 */
+    iret = connect(connector, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
+    ok(iret == 0 || 
+        (iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK), "connecting to accepting socket failed, error %d\n", WSAGetLastError());
+
+    FD_ZERO ( &fds_accept );
+    FD_ZERO ( &fds_send );
+
+    FD_SET ( listener, &fds_accept );
+    FD_SET ( connector, &fds_send );
+
+    buffer[0] = '0';
+    got = 0;
+    conn1 = 0;
+
+    for (i = 0; i < 4000; ++i)
+    {
+        wsa_ok ( ( select ( 0, &fds_accept, &fds_send, NULL, &timeout ) ), SOCKET_ERROR !=, 
+            "select_server (%x): select() failed: %d\n" );
+
+        /* check for incoming requests */
+        if ( FD_ISSET ( listener, &fds_accept ) ) {
+            got++;
+            if (got == 1) {
+                SOCKET tmp = WSAAccept(listener, NULL, NULL, (LPCONDITIONPROC) AlwaysDeferConditionFunc, NULL);
+                ok(tmp == INVALID_SOCKET && WSAGetLastError() == WSATRY_AGAIN, "Failed to defer connection\n");
+                bret = pAcceptEx(listener, acceptor, buffer, 0,
+                                    sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
+                                    &bytesReturned, &overlapped);
+                ok(bret == FALSE && WSAGetLastError() == ERROR_IO_PENDING, "AcceptEx returned %d + errno %d\n", bret, WSAGetLastError());
+            }
+            else if (got == 2) {
+                /* this should be socket #2 */
+                SOCKET tmp = accept(listener, NULL, NULL);
+                ok(tmp != INVALID_SOCKET, "accept failed %d\n", WSAGetLastError());
+                closesocket(tmp);
+            }
+            else {
+                ok(FALSE, "Got more than 2 connections?\n");
+            }
+        }
+        if ( conn1 && FD_ISSET ( connector2, &fds_send ) ) {
+            /* Send data on second socket, and stop */
+            send(connector2, "2", 1, 0);
+            FD_CLR ( connector2, &fds_send );
+
+            break;
+        }
+        if ( FD_ISSET ( connector, &fds_send ) ) {
+            /* Once #1 is connected, allow #2 to connect */
+            conn1 = 1;
+
+            send(connector, "1", 1, 0);
+            FD_CLR ( connector, &fds_send );
+
+            iret = connect(connector2, (struct sockaddr*)&bindAddress, sizeof(bindAddress));
+            ok(iret == 0 || 
+                (iret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK), "connecting to accepting socket failed, error %d\n", WSAGetLastError());
+            FD_SET ( connector2, &fds_send );
+        }
+    }
+
+    ok (got == 2, "Did not get both connections\n");
+
+    dwret = WaitForSingleObject(overlapped.hEvent, 0);
+    ok(dwret == WAIT_OBJECT_0, "Waiting for accept event failed with %d + errno %d\n", dwret, GetLastError());
+
+    bret = GetOverlappedResult((HANDLE)listener, &overlapped, &bytesReturned, FALSE);
+    ok(bret, "GetOverlappedResult failed, error %d\n", GetLastError());
+    ok(bytesReturned == 0, "bytesReturned isn't supposed to be %d\n", bytesReturned);
+
+    set_blocking(acceptor, TRUE);
+    iret = recv( acceptor, buffer, 2, 0);
+    ok(iret == 1, "Failed to get data, %d\n", iret);
+
+    ok(buffer[0] == '1', "The wrong first client was accepted by acceptex: %c != 1\n", buffer[0]);
 
     closesocket(connector);
     connector = INVALID_SOCKET;
@@ -2756,6 +2875,8 @@ end:
         closesocket(acceptor);
     if (connector != INVALID_SOCKET)
         closesocket(connector);
+    if (connector2 != INVALID_SOCKET)
+        closesocket(connector2);
 }
 
 /**************** Main program  ***************/


Reply via email to