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