[libvirt] [PATCH 08/12] client rpc: Separate call creation from running IO loop

Jiri Denemark jdenemar at redhat.com
Tue Jun 12 23:29:26 UTC 2012


This makes it possible to create and queue new calls while we are
running IO loop.
---
 src/rpc/virnetclient.c |   85 ++++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 31 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index e9898be..b956f6e 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1642,53 +1642,38 @@ done:
 }
 
 
-/*
- * Returns 1 if the call was queued and will be completed later (only
- * for nonBlock==true), 0 if the call was completed and -1 on error.
- */
-static int virNetClientSendInternal(virNetClientPtr client,
-                                    virNetMessagePtr msg,
-                                    bool expectReply,
-                                    bool nonBlock)
+static virNetClientCallPtr
+virNetClientCallNew(virNetMessagePtr msg,
+                    bool expectReply,
+                    bool nonBlock)
 {
-    virNetClientCallPtr call;
-    int ret = -1;
-
-    PROBE(RPC_CLIENT_MSG_TX_QUEUE,
-          "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
-          client, msg->bufferLength,
-          msg->header.prog, msg->header.vers, msg->header.proc,
-          msg->header.type, msg->header.status, msg->header.serial);
+    virNetClientCallPtr call = NULL;
 
     if (expectReply &&
         (msg->bufferLength != 0) &&
         (msg->header.status == VIR_NET_CONTINUE)) {
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
-                    _("Attempt to send an asynchronous message with a synchronous reply"));
-        return -1;
+                    _("Attempt to send an asynchronous message with"
+                      " a synchronous reply"));
+        goto error;
     }
 
     if (expectReply && nonBlock) {
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
-                    _("Attempt to send a non-blocking message with a synchronous reply"));
-        return -1;
+                    _("Attempt to send a non-blocking message with"
+                      " a synchronous reply"));
+        goto error;
     }
 
     if (VIR_ALLOC(call) < 0) {
         virReportOOMError();
-        return -1;
-    }
-
-    if (!client->sock || client->wantClose) {
-        virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
-                    _("client socket is closed"));
-        goto cleanup;
+        goto error;
     }
 
     if (virCondInit(&call->cond) < 0) {
         virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("cannot initialize condition variable"));
-        goto cleanup;
+        goto error;
     }
 
     msg->donefds = 0;
@@ -1699,8 +1684,48 @@ static int virNetClientSendInternal(virNetClientPtr client,
     call->msg = msg;
     call->expectReply = expectReply;
     call->nonBlock = nonBlock;
-    call->haveThread = true;
 
+    VIR_DEBUG("New call %p: msg=%p, expectReply=%d, nonBlock=%d",
+              call, msg, expectReply, nonBlock);
+
+    return call;
+
+error:
+    VIR_FREE(call);
+    return NULL;
+}
+
+
+/*
+ * Returns 1 if the call was queued and will be completed later (only
+ * for nonBlock==true), 0 if the call was completed and -1 on error.
+ */
+static int virNetClientSendInternal(virNetClientPtr client,
+                                    virNetMessagePtr msg,
+                                    bool expectReply,
+                                    bool nonBlock)
+{
+    virNetClientCallPtr call;
+    int ret = -1;
+
+    PROBE(RPC_CLIENT_MSG_TX_QUEUE,
+          "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u",
+          client, msg->bufferLength,
+          msg->header.prog, msg->header.vers, msg->header.proc,
+          msg->header.type, msg->header.status, msg->header.serial);
+
+    if (!client->sock || client->wantClose) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
+                    _("client socket is closed"));
+        return -1;
+    }
+
+    if (!(call = virNetClientCallNew(msg, expectReply, nonBlock))) {
+        virReportOOMError();
+        return -1;
+    }
+
+    call->haveThread = true;
     ret = virNetClientIO(client, call);
 
     /* If queued, the call will be finished and freed later by another thread;
@@ -1709,8 +1734,6 @@ static int virNetClientSendInternal(virNetClientPtr client,
         return 1;
 
     ignore_value(virCondDestroy(&call->cond));
-
-cleanup:
     VIR_FREE(call);
     return ret;
 }
-- 
1.7.10.2




More information about the libvir-list mailing list