server: Move socket async activation to sock_poll_event.
authorMike Kaplinskiy <mike.kaplinskiy@gmail.com>
Sat, 15 May 2010 05:18:20 +0000 (01:18 -0400)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 17 May 2010 12:41:33 +0000 (14:41 +0200)
dlls/ws2_32/tests/sock.c
server/async.c
server/file.h
server/sock.c

index 882bf226192379095de2de61591b4df603783523..6356d9f474d71a63ca3a55ffc5651907f566e71d 100644 (file)
@@ -3133,10 +3133,10 @@ static void test_events(int useMessages)
     ok(ret == 2, "Failed to send buffer %d err %d\n", ret, GetLastError());
     broken_seq[0] = read_read_seq; /* win9x */
     broken_seq[1] = NULL;
-    if (useMessages) /* we like to erase pmask in server, so we have varying behavior here */
-        todo_wine ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
-    else
-        ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
+    /* we like to erase pmask in server, so we have varying behavior here *
+     * it is only fixed for now because we refuse to send notifications with
+     * any kind of asyncs requests running */
+    ok_event_seq(src, hEvent, empty_seq, broken_seq, 0);
 
     dwRet = WaitForSingleObject(ov.hEvent, 100);
     ok(dwRet == WAIT_OBJECT_0, "Failed to wait for recv message: %d - %d\n", dwRet, GetLastError());
index 73cd76de3e15e55648a5f83e8cc2aa3c8862bff6..dd28dfffccd0bf03ab59bbaa079ee92dff59d9bd 100644 (file)
@@ -276,6 +276,12 @@ void async_set_result( struct object *obj, unsigned int status, unsigned int tot
     }
 }
 
+/* check if there are any queued async operations */
+int async_queued( struct async_queue *queue )
+{
+    return queue && list_head( &queue->queue );
+}
+
 /* check if an async operation is waiting to be alerted */
 int async_waiting( struct async_queue *queue )
 {
index 03cea89bd58561f3c996f68bac19974a65765f2b..9a348bfd572b04b476d89cce41f6e2296b644162 100644 (file)
@@ -146,6 +146,7 @@ extern struct async *create_async( struct thread *thread, struct async_queue *qu
 extern void async_set_timeout( struct async *async, timeout_t timeout, unsigned int status );
 extern void async_set_result( struct object *obj, unsigned int status,
                               unsigned int total, client_ptr_t apc );
+extern int async_queued( struct async_queue *queue );
 extern int async_waiting( struct async_queue *queue );
 extern void async_terminate( struct async *async, unsigned int status );
 extern int async_wake_up_by( struct async_queue *queue, struct process *process,
index d2348e4a1477aa25eb481166b4fce3d5c0d46a4a..34ec1768b77f7d3188a3d6c8a1404ecddfb25afc 100644 (file)
@@ -255,28 +255,14 @@ static int sock_reselect( struct sock *sock )
 }
 
 /* wake anybody waiting on the socket event or send the associated message */
-static void sock_wake_up( struct sock *sock, int pollev )
+static void sock_wake_up( struct sock *sock )
 {
     unsigned int events = sock->pmask & sock->mask;
     int i;
-    int async_active = 0;
-
-    if ( pollev & (POLLIN|POLLPRI|POLLERR|POLLHUP) && async_waiting( sock->read_q ))
-    {
-        if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock );
-        async_wake_up( sock->read_q, STATUS_ALERTED );
-        async_active = 1;
-    }
-    if ( pollev & (POLLOUT|POLLERR|POLLHUP) && async_waiting( sock->write_q ))
-    {
-        if (debug_level) fprintf( stderr, "activating write queue for socket %p\n", sock );
-        async_wake_up( sock->write_q, STATUS_ALERTED );
-        async_active = 1;
-    }
 
     /* Do not signal events if there are still pending asynchronous IO requests */
     /* We need this to delay FD_CLOSE events until all pending overlapped requests are processed */
-    if ( !events || async_active ) return;
+    if ( !events || async_queued( sock->read_q ) || async_queued( sock->write_q ) ) return;
 
     if (sock->event)
     {
@@ -437,7 +423,21 @@ static void sock_poll_event( struct fd *fd, int event )
     }
 
     /* wake up anyone waiting for whatever just happened */
-    if ( sock->pmask & sock->mask || sock->flags & WSA_FLAG_OVERLAPPED ) sock_wake_up( sock, event );
+    sock_wake_up( sock );
+
+    if ( sock->flags & WSA_FLAG_OVERLAPPED )
+    {
+        if ( event & (POLLIN|POLLPRI|POLLERR|POLLHUP) && async_waiting( sock->read_q ))
+        {
+            if (debug_level) fprintf( stderr, "activating read queue for socket %p\n", sock );
+            async_wake_up( sock->read_q, STATUS_ALERTED );
+        }
+        if ( event & (POLLOUT|POLLERR|POLLHUP) && async_waiting( sock->write_q ))
+        {
+            if (debug_level) fprintf( stderr, "activating write queue for socket %p\n", sock );
+            async_wake_up( sock->write_q, STATUS_ALERTED );
+        }
+    }
 
     /* if anyone is stupid enough to wait on the socket object itself,
      * maybe we should wake them up too, just in case? */
@@ -876,7 +876,7 @@ DECL_HANDLER(set_socket_event)
        it is possible that FD_CONNECT or FD_ACCEPT network events has happened
        before a WSAEventSelect() was done on it.
        (when dealing with Asynchronous socket)  */
-    if (sock->pmask & sock->mask) sock_wake_up( sock, pollev );
+    sock_wake_up( sock );
 
     if (old_event) release_object( old_event ); /* we're through with it */
     release_object( &sock->obj );