From 35e56fb042e60d2182caa0ee25ad9ddba515e12d Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 21 Jun 2014 21:50:40 +0200 Subject: [PATCH] server: Avoid invalid memory access when thread is killed while in wake_up(). (Valgrind). --- server/thread.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server/thread.c b/server/thread.c index b310e930f1d..50d694098b8 100644 --- a/server/thread.c +++ b/server/thread.c @@ -700,7 +700,7 @@ static int send_thread_wakeup( struct thread *thread, client_ptr_t cookie, int s } /* attempt to wake up a thread */ -/* return >0 if OK, 0 if the wait condition is still not satisfied */ +/* return >0 if OK, 0 if the wait condition is still not satisfied and -1 on error */ int wake_thread( struct thread *thread ) { int signaled, count; @@ -714,7 +714,10 @@ int wake_thread( struct thread *thread ) if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled ); end_wait( thread ); if (send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */ - break; + { + if (!count) count = -1; + break; + } } return count; } @@ -865,12 +868,13 @@ static timeout_t select_on( const select_op_t *select_op, data_size_t op_size, c void wake_up( struct object *obj, int max ) { struct list *ptr; + int ret; LIST_FOR_EACH( ptr, &obj->wait_queue ) { struct wait_queue_entry *entry = LIST_ENTRY( ptr, struct wait_queue_entry, entry ); - if (!wake_thread( get_wait_queue_thread( entry ))) continue; - if (max && !--max) break; + if (!(ret = wake_thread( get_wait_queue_thread( entry )))) continue; + if (ret > 0 && max && !--max) break; /* restart at the head of the list since a wake up can change the object wait queue */ ptr = &obj->wait_queue; }