From 44bf83e313b7567be1097c3e971b3e2b6c8e3601 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Tue, 11 Oct 2016 13:44:21 +0200 Subject: [PATCH] Clean timer in virObjectEventStateFlush If the last event callback is unregistered while the event loop is dispatching, it is only marked as deleted, but not removed. The number of callbacks is more than zero in that case, so the timer is not removed. Because it can be removed in this function now (but also accessed afterwards so that we set 'isDispatching = false' and have it locked), we need to temporarily increase the reference counter of the state for the duration of this function. Signed-off-by: Martin Kletzander --- src/conf/object_event.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/conf/object_event.c b/src/conf/object_event.c index 8f2c2d0f20..e5f942f0cc 100644 --- a/src/conf/object_event.c +++ b/src/conf/object_event.c @@ -807,6 +807,9 @@ virObjectEventStateFlush(virObjectEventStatePtr state) { virObjectEventQueue tempQueue; + /* We need to lock as well as ref due to the fact that we might + * unref the state we're working on in this very function */ + virObjectRef(state); virObjectLock(state); state->isDispatching = true; @@ -826,8 +829,13 @@ virObjectEventStateFlush(virObjectEventStatePtr state) /* Purge any deleted callbacks */ virObjectEventCallbackListPurgeMarked(state->callbacks); + /* If we purged all callbacks, we need to remove the timeout as + * well like virObjectEventStateDeregisterID() would do. */ + virObjectEventStateCleanupTimer(state, true); + state->isDispatching = false; virObjectUnlock(state); + virObjectUnref(state); }