From 933ad860029990449d30018486b58e9b95edff70 Mon Sep 17 00:00:00 2001 From: Pavel Hrdina Date: Thu, 6 Feb 2020 13:00:25 +0100 Subject: [PATCH] tests: fix deadlock in eventtest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a race deadlock in eventtest after the recent rewrite to drop GNULIB from libvirt code base. The issue happens when the callbacks testPipeReader() or testTimer() are called before waitEvents() starts waiting on `eventThreadCond`. It will never happen because the callbacks are already done and there is nothing that will signal the condition again. Reported-by: Peter Krempa Signed-off-by: Pavel Hrdina Reviewed-by: Daniel P. Berrangé Reviewed-by: Peter Krempa --- tests/eventtest.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/eventtest.c b/tests/eventtest.c index 9855b578fb..06b5e7b20c 100644 --- a/tests/eventtest.c +++ b/tests/eventtest.c @@ -43,6 +43,7 @@ VIR_LOG_INIT("tests.eventtest"); static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t eventThreadCond = PTHREAD_COND_INITIALIZER; +static bool eventThreadSignaled; static struct handleInfo { int pipeFD[2]; @@ -138,8 +139,9 @@ testPipeReader(int watch, int fd, int events, void *data) virEventRemoveHandle(info->delete); cleanup: - pthread_mutex_unlock(&eventThreadMutex); pthread_cond_signal(&eventThreadCond); + eventThreadSignaled = true; + pthread_mutex_unlock(&eventThreadMutex); } @@ -164,8 +166,9 @@ testTimer(int timer, void *data) virEventRemoveTimeout(info->delete); cleanup: - pthread_mutex_unlock(&eventThreadMutex); pthread_cond_signal(&eventThreadCond); + eventThreadSignaled = true; + pthread_mutex_unlock(&eventThreadMutex); } G_GNUC_NORETURN static void *eventThreadLoop(void *data G_GNUC_UNUSED) { @@ -185,7 +188,10 @@ waitEvents(int nhandle, int ntimer) VIR_DEBUG("Wait events nhandle %d ntimer %d", nhandle, ntimer); while (ngothandle != nhandle || ngottimer != ntimer) { - pthread_cond_wait(&eventThreadCond, &eventThreadMutex); + while (!eventThreadSignaled) + pthread_cond_wait(&eventThreadCond, &eventThreadMutex); + + eventThreadSignaled = false; ngothandle = ngottimer = 0; for (i = 0; i < NUM_FDS; i++) {