]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: avoid deadlock in qemuDomainObjStopWorker
authorNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Thu, 23 Jul 2020 08:02:59 +0000 (11:02 +0300)
committerNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Mon, 7 Sep 2020 06:33:59 +0000 (09:33 +0300)
We are dropping the only reference here so that the event loop thread
is going to be exited synchronously. In order to avoid deadlocks we
need to unlock the VM so that any handler being called can finish
execution and thus even loop thread be finished too.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/qemu/qemu_domain.c

index b1884b6c849a4b5cbadda64dcf53e5cec02dd172..0ed132a8295ee0433928fa2fb0c5f8ca9606d298 100644 (file)
@@ -1722,11 +1722,21 @@ void
 qemuDomainObjStopWorker(virDomainObjPtr dom)
 {
     qemuDomainObjPrivatePtr priv = dom->privateData;
+    virEventThread *eventThread;
 
-    if (priv->eventThread) {
-        g_object_unref(priv->eventThread);
-        priv->eventThread = NULL;
-    }
+    if (!priv->eventThread)
+        return;
+
+    /*
+     * We are dropping the only reference here so that the event loop thread
+     * is going to be exited synchronously. In order to avoid deadlocks we
+     * need to unlock the VM so that any handler being called can finish
+     * execution and thus even loop thread be finished too.
+     */
+    eventThread = g_steal_pointer(&priv->eventThread);
+    virObjectUnlock(dom);
+    g_object_unref(eventThread);
+    virObjectLock(dom);
 }