Alexandre Julliard : server: Call the satisfied methods after removing the thread wait.

Alexandre Julliard julliard at winehq.org
Wed Jun 28 15:10:25 CDT 2017


Module: wine
Branch: master
Commit: e0760ce933c4216bdb388a832be6792dccd7784c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e0760ce933c4216bdb388a832be6792dccd7784c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jun 28 12:23:00 2017 +0200

server: Call the satisfied methods after removing the thread wait.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/thread.c | 54 +++++++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/server/thread.c b/server/thread.c
index 10a5bf1..70f5f28 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -583,7 +583,7 @@ void make_wait_abandoned( struct wait_queue_entry *entry )
 }
 
 /* finish waiting */
-static void end_wait( struct thread *thread )
+static unsigned int end_wait( struct thread *thread, unsigned int status )
 {
     struct thread_wait *wait = thread->wait;
     struct wait_queue_entry *entry;
@@ -591,10 +591,26 @@ static void end_wait( struct thread *thread )
 
     assert( wait );
     thread->wait = wait->next;
+
+    if (status < wait->count)  /* wait satisfied, tell it to the objects */
+    {
+        if (wait->select == SELECT_WAIT_ALL)
+        {
+            for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
+                entry->obj->ops->satisfied( entry->obj, entry );
+        }
+        else
+        {
+            entry = wait->queues + status;
+            entry->obj->ops->satisfied( entry->obj, entry );
+        }
+        if (wait->abandoned) status += STATUS_ABANDONED_WAIT_0;
+    }
     for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
         entry->obj->ops->remove_queue( entry->obj, entry );
     if (wait->user) remove_timeout_user( wait->user );
     free( wait );
+    return status;
 }
 
 /* build the thread wait structure */
@@ -624,7 +640,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
         if (!obj->ops->add_queue( obj, entry ))
         {
             wait->count = i;
-            end_wait( current );
+            end_wait( current, get_error() );
             return 0;
         }
     }
@@ -672,25 +688,14 @@ static int check_wait( struct thread *thread )
          * want to do something when signaled, even if others are not */
         for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
             not_ok |= !entry->obj->ops->signaled( entry->obj, entry );
-        if (not_ok) goto other_checks;
-        /* Wait satisfied: tell it to all objects */
-        for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
-            entry->obj->ops->satisfied( entry->obj, entry );
-        return wait->abandoned ? STATUS_ABANDONED_WAIT_0 : STATUS_WAIT_0;
+        if (!not_ok) return STATUS_WAIT_0;
     }
     else
     {
         for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
-        {
-            if (!entry->obj->ops->signaled( entry->obj, entry )) continue;
-            /* Wait satisfied: tell it to the object */
-            entry->obj->ops->satisfied( entry->obj, entry );
-            if (wait->abandoned) i += STATUS_ABANDONED_WAIT_0;
-            return i;
-        }
+            if (entry->obj->ops->signaled( entry->obj, entry )) return i;
     }
 
- other_checks:
     if ((wait->flags & SELECT_ALERTABLE) && !list_empty(&thread->user_apc)) return STATUS_USER_APC;
     if (wait->timeout <= current_time) return STATUS_TIMEOUT;
     return -1;
@@ -728,8 +733,8 @@ int wake_thread( struct thread *thread )
         if ((signaled = check_wait( thread )) == -1) break;
 
         cookie = thread->wait->cookie;
+        signaled = end_wait( thread, signaled );
         if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled );
-        end_wait( thread );
         if (cookie && send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */
         {
             if (!count) count = -1;
@@ -752,13 +757,9 @@ int wake_thread_queue_entry( struct wait_queue_entry *entry )
 
     assert( wait->select != SELECT_WAIT_ALL );
 
-    signaled = entry - wait->queues;
-    entry->obj->ops->satisfied( entry->obj, entry );
-    if (wait->abandoned) signaled += STATUS_ABANDONED_WAIT_0;
-
     cookie = wait->cookie;
+    signaled = end_wait( thread, entry - wait->queues );
     if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled );
-    end_wait( thread );
 
     if (!cookie || send_thread_wakeup( thread, cookie, signaled ) != -1)
         wake_thread( thread );  /* check other waits too */
@@ -778,7 +779,7 @@ static void thread_timeout( void *ptr )
     if (thread->suspend + thread->process->suspend > 0) return;  /* suspended, ignore it */
 
     if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=TIMEOUT\n", thread->id );
-    end_wait( thread );
+    end_wait( thread, STATUS_TIMEOUT );
 
     assert( cookie );
     if (send_thread_wakeup( thread, cookie, STATUS_TIMEOUT ) == -1) return;
@@ -836,7 +837,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
         {
             if (!signal_object( select_op->signal_and_wait.signal ))
             {
-                end_wait( current );
+                end_wait( current, get_error() );
                 return timeout;
             }
             /* check if we woke ourselves up */
@@ -863,8 +864,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
     if ((ret = check_wait( current )) != -1)
     {
         /* condition is already satisfied */
-        end_wait( current );
-        set_error( ret );
+        set_error( end_wait( current, ret ));
         return timeout;
     }
 
@@ -874,7 +874,7 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c
         if (!(current->wait->user = add_timeout_user( current->wait->timeout,
                                                       thread_timeout, current->wait )))
         {
-            end_wait( current );
+            end_wait( current, get_error() );
             return timeout;
         }
     }
@@ -1106,7 +1106,7 @@ void kill_thread( struct thread *thread, int violent_death )
                  thread->id, thread->exit_code );
     if (thread->wait)
     {
-        while (thread->wait) end_wait( thread );
+        while (thread->wait) end_wait( thread, STATUS_THREAD_IS_TERMINATING );
         send_thread_wakeup( thread, 0, thread->exit_code );
         /* if it is waiting on the socket, we don't need to send a SIGQUIT */
         violent_death = 0;




More information about the wine-cvs mailing list