]> xenbits.xensource.com Git - libvirt.git/commitdiff
docs: Document our event loop
authorMichal Privoznik <mprivozn@redhat.com>
Sun, 5 Jun 2016 04:58:54 +0000 (06:58 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 6 Jun 2016 15:35:44 +0000 (17:35 +0200)
I was asked the other day what's event loop and how libvirt uses
it. Well, I haven't found any good sources on the Internet so I
thought of writing the documentation on my own.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
docs/internals.html.in
docs/internals/eventloop.html.in [new file with mode: 0644]
docs/sitemap.html.in

index c30f52f9f0621a2885dc81dae69e077317a3fce3..fcc07580d01269144ec5ff5e3212590cc676ca5a 100644 (file)
@@ -14,6 +14,7 @@
       <li>Introduction to basic rules and guidelines for
       <a href="hacking.html">hacking</a> on libvirt code</li>
       <li>Guide to adding <a href="api_extension.html">public APIs</a></li>
+      <li>Insight into libvirt <a href="internals/eventloop.html">event loop and worker pool</a></li>
       <li>Approach for <a href="internals/command.html">spawning commands</a>
       from libvirt driver code</li>
       <li>The libvirt <a href="internals/rpc.html">RPC infrastructure</a></li>
diff --git a/docs/internals/eventloop.html.in b/docs/internals/eventloop.html.in
new file mode 100644 (file)
index 0000000..a01e104
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <body>
+    <h1>Libvirt's event loop</h1>
+
+    <ul id="toc"></ul>
+
+    <p>
+      This page describes the event loop approach used in
+      libvirt. Both server and client.
+    </p>
+
+    <h2><a name="event_loop">Event driven programming</a></h2>
+
+    <p>Traditionally, a program simply ran once, then terminated.
+    This type of program was very common in the early days of
+    computing, and lacked any form of user interactivity. This is
+    still used frequently, particularly in small one purpose
+    programs.</p>
+
+    <p>However, that approach is not suitable for all the types
+    of applications. For instance graphical applications spend
+    most of their run time waiting for an input from user. Only
+    after it happened (in our example a button was clicked, a key
+    pressed, etc.) an event is generated to which they respond
+    by executing desired function. If generalized, this is how
+    many long running programs (daemons) work. Even those who are
+    not waiting for direct user input and have no graphical
+    interface. Such as Libvirt.</p>
+
+    <img alt="event loop" src="http://libvirt.org/git/?p=libvirt-media.git;a=blob_plain;f=png/event_loop_simple.png;hb=HEAD"/>
+
+    <p>In Libvirt this approach is used in combination with
+    <code>poll(2)</code> as all the communication with its
+    clients (and domains it manages too) happens through sockets.
+    Therefore whenever new client connects, it is given exclusive
+    file descriptor which is then watched for incoming events,
+    e.g. messages. </p>
+
+    <h2><a name="api">The event loop API</a></h2>
+
+    <p>To work with event loop from our code we have plenty of
+    APIs.</p>
+
+    <ul>
+      <li><code>virEventAddHandle</code>: Registers a
+        callback for monitoring file handle events.</li>
+      <li><code>virEventUpdateHandle</code>: Change set of events
+        monitored file handle is being watched for.</li>
+      <li><code>virEventRemoveHandle</code>: Unregisters
+        previously registered file handle so that it is no
+        longer monitored for any events.</li>
+      <li><code>virEventAddTimeout</code>: Registers a
+        callback for timer event.</li>
+      <li><code>virEventUpdateTimeout</code>: Changes frequency
+        for a timer.</li>
+      <li><code>virEventRemoveTimeout</code>: Unregisters
+        a timer.</li>
+    </ul>
+
+    <p>For more information on these APIs continue reading <a
+    href="../html/libvirt-libvirt-event.html">here</a>.</p>
+
+    <h2><a name="worker_pool">Worker pool</a></h2>
+
+    <p>Looking back at the image above we can see one big
+    limitation. While processing a message event loop is blocked
+    and for an outside observer unresponsive. This is not
+    acceptable for Libvirt. Therefore we have came up with the
+    following solution.</p>
+
+    <img alt="event loop" src="http://libvirt.org/git/?p=libvirt-media.git;a=blob_plain;f=png/event_loop_worker.png;hb=HEAD"/>
+
+    <p>The event loop does only necessary minimum and hand over
+    message processing to another thread. In fact, there can be
+    as many processing threads as configured increasing
+    processing power.</p>
+
+    <p>To break this high level description into smaller pieces,
+    here is what happens when user calls an API:</p>
+    <ol>
+      <li>User (or management application) calls a Libvirt API.
+      Depending on the connection URI, this may or may not
+      involve server. Well, for the sake of our
+      demonstration we assume the former.</li>
+      <li>Remote driver encodes the API among it's arguments
+      into an <a href="rpc.html">RPC message</a> and sends
+      it to the server.</li>
+      <li>Here, server is waiting in <code>poll(2)</code> for
+      an event, like incoming message.</li>
+      <li>As soon as the first bytes of message are received,
+      even loop wakes up and server starts reading the
+      whole message.</li>
+      <li>Once fully read, the event loop notifies threads
+      known as worker threads from which one picks the incoming
+      message, decodes and process it.</li>
+      <li>As soon as API execution is finished, a reply is sent
+      to the client.</li>
+    </ol>
+
+    <p>In case that there's no free worker to process an incoming
+    message in step 5, message is placed at the end of a message
+    queue and is processed in next iteration.</p>
+  </body>
+</html>
index d5cf723f77006b6376f2d3efc9dbcbc2c93c9edc..757d5aa9d21533c90867c4b2813f075d6bb874fc 100644 (file)
                 <a href="api_extension.html">API extensions</a>
                 <span>Adding new public libvirt APIs</span>
               </li>
+              <li>
+                <a href="internals/eventloop.html">Event loop and worker pool</a>
+                <span>Libvirt's event loop and worker pool mode</span>
+              </li>
               <li>
                 <a href="internals/command.html">Spawning commands</a>
                 <span>Spawning commands from libvirt driver code</span>