]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
rpc: Fix client crash on connection close
authorJiri Denemark <jdenemar@redhat.com>
Fri, 2 Mar 2012 18:57:27 +0000 (19:57 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Mon, 5 Mar 2012 10:30:02 +0000 (11:30 +0100)
A multi-threaded client with event loop may crash if one of its threads
closes a connection while event loop is in the middle of sending
keep-alive message (either request or response). The right place for it
is inside virNetClientIOEventLoop() between poll() and
virNetClientLock(). We should only close a connection directly if no-one
is using it and defer the closing to the last user otherwise. So far we
only did so if the close was initiated by keep-alive timeout.

src/rpc/virnetclient.c

index ffe067c76d81c0f32525ff848e5d3f09142a79f7..99ab8007f280b09007c320eec0b91f548b26bcdc 100644 (file)
@@ -108,8 +108,6 @@ struct _virNetClient {
 };
 
 
-static void virNetClientRequestClose(virNetClientPtr client);
-
 static void virNetClientLock(virNetClientPtr client)
 {
     virMutexLock(&client->lock);
@@ -253,7 +251,7 @@ virNetClientKeepAliveStart(virNetClientPtr client,
 static void
 virNetClientKeepAliveDeadCB(void *opaque)
 {
-    virNetClientRequestClose(opaque);
+    virNetClientClose(opaque);
 }
 
 static int
@@ -512,19 +510,11 @@ virNetClientCloseLocked(virNetClientPtr client)
 
 void virNetClientClose(virNetClientPtr client)
 {
+    VIR_DEBUG("client=%p", client);
+
     if (!client)
         return;
 
-    virNetClientLock(client);
-    virNetClientCloseLocked(client);
-    virNetClientUnlock(client);
-}
-
-static void
-virNetClientRequestClose(virNetClientPtr client)
-{
-    VIR_DEBUG("client=%p", client);
-
     virNetClientLock(client);
 
     /* If there is a thread polling for data on the socket, set wantClose flag