[libvirt] PATCH: 6/25: Avoid event loop wakups in remote driver

Daniel P. Berrange berrange at redhat.com
Tue Jan 13 17:40:43 UTC 2009


When going into the call() method, we temporarily disable the
event wakup callback. The call() method is already processing
any async messages which arrive, so letting the main event loop
wakup here is inefficient, and indeed will block the main event
loop on the mutex while the main thread is in call(). We really
don't want that !

 remote_internal.c |   42 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 8 deletions(-)

Daniel

diff --git a/src/remote_internal.c b/src/remote_internal.c
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -753,9 +753,7 @@ doRemoteOpen (virConnectPtr conn,
     DEBUG0("Adding Handler for remote events");
     /* Set up a callback to listen on the socket data */
     if ((priv->watch = virEventAddHandle(priv->sock,
-                                         VIR_EVENT_HANDLE_READABLE |
-                                         VIR_EVENT_HANDLE_ERROR |
-                                         VIR_EVENT_HANDLE_HANGUP,
+                                         VIR_EVENT_HANDLE_READABLE,
                                          remoteDomainEventFired,
                                          conn, NULL)) < 0) {
         DEBUG0("virEventAddHandle failed: No addHandleImpl defined."
@@ -5559,11 +5557,11 @@ static int really_read (virConnectPtr co
  * else Bad Things will happen in the XDR code.
  */
 static int
-call (virConnectPtr conn, struct private_data *priv,
-      int flags /* if we are in virConnectOpen */,
-      int proc_nr,
-      xdrproc_t args_filter, char *args,
-      xdrproc_t ret_filter, char *ret)
+doCall (virConnectPtr conn, struct private_data *priv,
+        int flags /* if we are in virConnectOpen */,
+        int proc_nr,
+        xdrproc_t args_filter, char *args,
+        xdrproc_t ret_filter, char *ret)
 {
     char buffer[REMOTE_MESSAGE_MAX];
     char buffer2[4];
@@ -5752,6 +5750,34 @@ retry_read:
         xdr_destroy (&xdr);
         return -1;
     }
+}
+
+
+static int
+call (virConnectPtr conn, struct private_data *priv,
+      int flags /* if we are in virConnectOpen */,
+      int proc_nr,
+      xdrproc_t args_filter, char *args,
+      xdrproc_t ret_filter, char *ret)
+{
+    int rv;
+    /*
+     * Avoid needless wake-ups of the event loop in the
+     * case where this call is being made from a different
+     * thread than the event loop. These wake-ups would
+     * cause the event loop thread to be blocked on the
+     * mutex for the duration of the call
+     */
+    if (priv->watch >= 0)
+        virEventUpdateHandle(priv->watch, 0);
+
+    rv = doCall(conn, priv,flags, proc_nr,
+                args_filter, args,
+                ret_filter, ret);
+
+    if (priv->watch >= 0)
+        virEventUpdateHandle(priv->watch, VIR_EVENT_HANDLE_READABLE);
+    return rv;
 }
 
 static int

-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list