]> git.llucax.com Git - software/libev.git/blobdiff - ev.html
*** empty log message ***
[software/libev.git] / ev.html
diff --git a/ev.html b/ev.html
index 6a8ead5f147221649e5a84a9e6e9b41ccae48f67..b13b6ae5983e4dc9729deea5167410e674129c5d 100644 (file)
--- a/ev.html
+++ b/ev.html
@@ -6,7 +6,7 @@
        <meta name="description" content="Pod documentation for libev" />
        <meta name="inputfile" content="&lt;standard input&gt;" />
        <meta name="outputfile" content="&lt;standard output&gt;" />
        <meta name="description" content="Pod documentation for libev" />
        <meta name="inputfile" content="&lt;standard input&gt;" />
        <meta name="outputfile" content="&lt;standard output&gt;" />
-       <meta name="created" content="Sat Nov 24 17:31:33 2007" />
+       <meta name="created" content="Mon Nov 26 11:20:35 2007" />
        <meta name="generator" content="Pod::Xhtml 1.57" />
 <link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
 <body>
        <meta name="generator" content="Pod::Xhtml 1.57" />
 <link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
 <body>
@@ -52,6 +52,7 @@
 <li><a href="#EXAMPLES">EXAMPLES</a></li>
 </ul>
 </li>
 <li><a href="#EXAMPLES">EXAMPLES</a></li>
 </ul>
 </li>
+<li><a href="#COMPLEXITIES">COMPLEXITIES</a></li>
 <li><a href="#AUTHOR">AUTHOR</a>
 </li>
 </ul><hr />
 <li><a href="#AUTHOR">AUTHOR</a>
 </li>
 </ul><hr />
@@ -1128,10 +1129,20 @@ callback, free it. Alos, use no error checking, as usual.</p>
 <p>Prepare and check watchers are usually (but not always) used in tandem:
 prepare watchers get invoked before the process blocks and check watchers
 afterwards.</p>
 <p>Prepare and check watchers are usually (but not always) used in tandem:
 prepare watchers get invoked before the process blocks and check watchers
 afterwards.</p>
+<p>You <i>must not</i> call <code>ev_loop</code> or similar functions that enter
+the current event loop from either <code>ev_prepare</code> or <code>ev_check</code>
+watchers. Other loops than the current one are fine, however. The
+rationale behind this is that you do not need to check for recursion in
+those watchers, i.e. the sequence will always be <code>ev_prepare</code>, blocking,
+<code>ev_check</code> so if you have one watcher of each kind they will always be
+called in pairs bracketing the blocking call.</p>
 <p>Their main purpose is to integrate other event mechanisms into libev and
 their use is somewhat advanced. This could be used, for example, to track
 variable changes, implement your own watchers, integrate net-snmp or a
 <p>Their main purpose is to integrate other event mechanisms into libev and
 their use is somewhat advanced. This could be used, for example, to track
 variable changes, implement your own watchers, integrate net-snmp or a
-coroutine library and lots more.</p>
+coroutine library and lots more. They are also occasionally useful if
+you cache some data and want to flush it before blocking (for example,
+in X programs you might want to do an <code>XFlush ()</code> in an <code>ev_prepare</code>
+watcher).</p>
 <p>This is done by examining in each prepare call which file descriptors need
 to be watched by the other library, registering <code>ev_io</code> watchers for
 them and starting an <code>ev_timer</code> watcher for any timeouts (many libraries
 <p>This is done by examining in each prepare call which file descriptors need
 to be watched by the other library, registering <code>ev_io</code> watchers for
 them and starting an <code>ev_timer</code> watcher for any timeouts (many libraries
@@ -1157,11 +1168,64 @@ parameters of any kind. There are <code>ev_prepare_set</code> and <code>ev_check
 macros, but using them is utterly, utterly and completely pointless.</p>
        </dd>
 </dl>
 macros, but using them is utterly, utterly and completely pointless.</p>
        </dd>
 </dl>
-<p>Example: *TODO*.</p>
+<p>Example: To include a library such as adns, you would add IO watchers
+and a timeout watcher in a prepare handler, as required by libadns, and
+in a check watcher, destroy them and call into libadns. What follows is
+pseudo-code only of course:</p>
+<pre>  static ev_io iow [nfd];
+  static ev_timer tw;
+
+  static void
+  io_cb (ev_loop *loop, ev_io *w, int revents)
+  {
+    // set the relevant poll flags
+    // could also call adns_processreadable etc. here
+    struct pollfd *fd = (struct pollfd *)w-&gt;data;
+    if (revents &amp; EV_READ ) fd-&gt;revents |= fd-&gt;events &amp; POLLIN;
+    if (revents &amp; EV_WRITE) fd-&gt;revents |= fd-&gt;events &amp; POLLOUT;
+  }
+
+  // create io watchers for each fd and a timer before blocking
+  static void
+  adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents)
+  {
+    int timeout = 3600000;truct pollfd fds [nfd];
+    // actual code will need to loop here and realloc etc.
+    adns_beforepoll (ads, fds, &amp;nfd, &amp;timeout, timeval_from (ev_time ()));
+
+    /* the callback is illegal, but won't be called as we stop during check */
+    ev_timer_init (&amp;tw, 0, timeout * 1e-3);
+    ev_timer_start (loop, &amp;tw);
+
+    // create on ev_io per pollfd
+    for (int i = 0; i &lt; nfd; ++i)
+      {
+        ev_io_init (iow + i, io_cb, fds [i].fd,
+          ((fds [i].events &amp; POLLIN ? EV_READ : 0)
+           | (fds [i].events &amp; POLLOUT ? EV_WRITE : 0)));
+
+        fds [i].revents = 0;
+        iow [i].data = fds + i;
+        ev_io_start (loop, iow + i);
+      }
+  }
+
+  // stop all watchers after blocking
+  static void
+  adns_check_cb (ev_loop *loop, ev_check *w, int revents)
+  {
+    ev_timer_stop (loop, &amp;tw);
+
+    for (int i = 0; i &lt; nfd; ++i)
+      ev_io_stop (loop, iow + i);
+
+    adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
+  }
 
 
 
 
 
 
 
 
+</pre>
 
 </div>
 <h2 id="code_ev_embed_code_when_one_backend_"><code>ev_embed</code> - when one backend isn't enough...</h2>
 
 </div>
 <h2 id="code_ev_embed_code_when_one_backend_"><code>ev_embed</code> - when one backend isn't enough...</h2>
@@ -1471,7 +1535,7 @@ in your include path (e.g. in libev/ when using -Ilibev):</p>
 
   ev_win32.c      required on win32 platforms only
 
 
   ev_win32.c      required on win32 platforms only
 
-  ev_select.c     only when select backend is enabled (which is is by default)
+  ev_select.c     only when select backend is enabled (which is by default)
   ev_poll.c       only when poll backend is enabled (disabled by default)
   ev_epoll.c      only when the epoll backend is enabled (disabled by default)
   ev_kqueue.c     only when the kqueue backend is enabled (disabled by default)
   ev_poll.c       only when poll backend is enabled (disabled by default)
   ev_epoll.c      only when the epoll backend is enabled (disabled by default)
   ev_kqueue.c     only when the kqueue backend is enabled (disabled by default)
@@ -1479,7 +1543,7 @@ in your include path (e.g. in libev/ when using -Ilibev):</p>
 
 </pre>
 <p><cite>ev.c</cite> includes the backend files directly when enabled, so you only need
 
 </pre>
 <p><cite>ev.c</cite> includes the backend files directly when enabled, so you only need
-to compile a single file.</p>
+to compile this single file.</p>
 
 </div>
 <h3 id="LIBEVENT_COMPATIBILITY_API">LIBEVENT COMPATIBILITY API</h3>
 
 </div>
 <h3 id="LIBEVENT_COMPATIBILITY_API">LIBEVENT COMPATIBILITY API</h3>
@@ -1504,8 +1568,8 @@ to compile a single file.</p>
 <div id="AUTOCONF_SUPPORT_CONTENT">
 <p>Instead of using <code>EV_STANDALONE=1</code> and providing your config in
 whatever way you want, you can also <code>m4_include([libev.m4])</code> in your
 <div id="AUTOCONF_SUPPORT_CONTENT">
 <p>Instead of using <code>EV_STANDALONE=1</code> and providing your config in
 whatever way you want, you can also <code>m4_include([libev.m4])</code> in your
-<cite>configure.ac</cite> and leave <code>EV_STANDALONE</code> off. <cite>ev.c</cite> will then include
-<cite>config.h</cite> and configure itself accordingly.</p>
+<cite>configure.ac</cite> and leave <code>EV_STANDALONE</code> undefined. <cite>ev.c</cite> will then
+include <cite>config.h</cite> and configure itself accordingly.</p>
 <p>For this of course you need the m4 file:</p>
 <pre>  libev.m4
 
 <p>For this of course you need the m4 file:</p>
 <pre>  libev.m4
 
@@ -1658,16 +1722,16 @@ though, and it must be identical each time.</p>
 
 </pre>
        </dd>
 
 </pre>
        </dd>
-       <dt>EV_CB_DECLARE(type)</dt>
-       <dt>EV_CB_INVOKE(watcher,revents)</dt>
-       <dt>ev_set_cb(ev,cb)</dt>
+       <dt>EV_CB_DECLARE (type)</dt>
+       <dt>EV_CB_INVOKE (watcher, revents)</dt>
+       <dt>ev_set_cb (ev, cb)</dt>
        <dd>
                <p>Can be used to change the callback member declaration in each watcher,
 and the way callbacks are invoked and set. Must expand to a struct member
 definition and a statement, respectively. See the <cite>ev.v</cite> header file for
 their default definitions. One possible use for overriding these is to
        <dd>
                <p>Can be used to change the callback member declaration in each watcher,
 and the way callbacks are invoked and set. Must expand to a struct member
 definition and a statement, respectively. See the <cite>ev.v</cite> header file for
 their default definitions. One possible use for overriding these is to
-avoid the ev_loop pointer as first argument in all cases, or to use method
-calls instead of plain function calls in C++.</p>
+avoid the <code>struct ev_loop *</code> as first argument in all cases, or to use
+method calls instead of plain function calls in C++.</p>
 
 </div>
 <h2 id="EXAMPLES">EXAMPLES</h2>
 
 </div>
 <h2 id="EXAMPLES">EXAMPLES</h2>
@@ -1693,8 +1757,34 @@ that everybody includes and which overrides some autoconf choices:</p>
 <pre>  #include &quot;ev_cpp.h&quot;
   #include &quot;ev.c&quot;
 
 <pre>  #include &quot;ev_cpp.h&quot;
   #include &quot;ev.c&quot;
 
+
+
+
 </pre>
 
 </pre>
 
+</div>
+<h1 id="COMPLEXITIES">COMPLEXITIES</h1><p><a href="#TOP" class="toplink">Top</a></p>
+<div id="COMPLEXITIES_CONTENT">
+               <p>In this section the complexities of (many of) the algorithms used inside
+libev will be explained. For complexity discussions about backends see the
+documentation for <code>ev_default_init</code>.</p>
+               <p>
+                       <dl>
+                               <dt>Starting and stopping timer/periodic watchers: O(log skipped_other_timers)</dt>
+                               <dt>Changing timer/periodic watchers (by autorepeat, again): O(log skipped_other_timers)</dt>
+                               <dt>Starting io/check/prepare/idle/signal/child watchers: O(1)</dt>
+                               <dt>Stopping check/prepare/idle watchers: O(1)</dt>
+                               <dt>Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % 16))</dt>
+                               <dt>Finding the next timer per loop iteration: O(1)</dt>
+                               <dt>Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)</dt>
+                               <dt>Activating one watcher: O(1)</dt>
+                       </dl>
+               </p>
+
+
+
+
+
 </div>
 <h1 id="AUTHOR">AUTHOR</h1><p><a href="#TOP" class="toplink">Top</a></p>
 <div id="AUTHOR_CONTENT">
 </div>
 <h1 id="AUTHOR">AUTHOR</h1><p><a href="#TOP" class="toplink">Top</a></p>
 <div id="AUTHOR_CONTENT">