mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-08 16:54:49 +00:00
tests: fix deadlock in eventtest
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 <pkrempa@redhat.com> Signed-off-by: Pavel Hrdina <phrdina@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
5e35d4a519
commit
933ad86002
@ -43,6 +43,7 @@ VIR_LOG_INIT("tests.eventtest");
|
|||||||
|
|
||||||
static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_cond_t eventThreadCond = PTHREAD_COND_INITIALIZER;
|
static pthread_cond_t eventThreadCond = PTHREAD_COND_INITIALIZER;
|
||||||
|
static bool eventThreadSignaled;
|
||||||
|
|
||||||
static struct handleInfo {
|
static struct handleInfo {
|
||||||
int pipeFD[2];
|
int pipeFD[2];
|
||||||
@ -138,8 +139,9 @@ testPipeReader(int watch, int fd, int events, void *data)
|
|||||||
virEventRemoveHandle(info->delete);
|
virEventRemoveHandle(info->delete);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
pthread_mutex_unlock(&eventThreadMutex);
|
|
||||||
pthread_cond_signal(&eventThreadCond);
|
pthread_cond_signal(&eventThreadCond);
|
||||||
|
eventThreadSignaled = true;
|
||||||
|
pthread_mutex_unlock(&eventThreadMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -164,8 +166,9 @@ testTimer(int timer, void *data)
|
|||||||
virEventRemoveTimeout(info->delete);
|
virEventRemoveTimeout(info->delete);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
pthread_mutex_unlock(&eventThreadMutex);
|
|
||||||
pthread_cond_signal(&eventThreadCond);
|
pthread_cond_signal(&eventThreadCond);
|
||||||
|
eventThreadSignaled = true;
|
||||||
|
pthread_mutex_unlock(&eventThreadMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
G_GNUC_NORETURN static void *eventThreadLoop(void *data G_GNUC_UNUSED) {
|
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",
|
VIR_DEBUG("Wait events nhandle %d ntimer %d",
|
||||||
nhandle, ntimer);
|
nhandle, ntimer);
|
||||||
while (ngothandle != nhandle || ngottimer != ntimer) {
|
while (ngothandle != nhandle || ngottimer != ntimer) {
|
||||||
pthread_cond_wait(&eventThreadCond, &eventThreadMutex);
|
while (!eventThreadSignaled)
|
||||||
|
pthread_cond_wait(&eventThreadCond, &eventThreadMutex);
|
||||||
|
|
||||||
|
eventThreadSignaled = false;
|
||||||
|
|
||||||
ngothandle = ngottimer = 0;
|
ngothandle = ngottimer = 0;
|
||||||
for (i = 0; i < NUM_FDS; i++) {
|
for (i = 0; i < NUM_FDS; i++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user