ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.html
(Generate patch)

Comparing libev/ev.html (file contents):
Revision 1.71 by root, Sat Dec 8 14:31:45 2007 UTC vs.
Revision 1.72 by root, Sat Dec 8 15:30:29 2007 UTC

4<head> 4<head>
5 <title>libev</title> 5 <title>libev</title>
6 <meta name="description" content="Pod documentation for libev" /> 6 <meta name="description" content="Pod documentation for libev" />
7 <meta name="inputfile" content="&lt;standard input&gt;" /> 7 <meta name="inputfile" content="&lt;standard input&gt;" />
8 <meta name="outputfile" content="&lt;standard output&gt;" /> 8 <meta name="outputfile" content="&lt;standard output&gt;" />
9 <meta name="created" content="Sat Dec 8 15:31:35 2007" /> 9 <meta name="created" content="Sat Dec 8 16:30:24 2007" />
10 <meta name="generator" content="Pod::Xhtml 1.57" /> 10 <meta name="generator" content="Pod::Xhtml 1.57" />
11<link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head> 11<link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
12<body> 12<body>
13<div class="pod"> 13<div class="pod">
14<!-- INDEX START --> 14<!-- INDEX START -->
1492 <p>Initialises and configures the prepare or check watcher - they have no 1492 <p>Initialises and configures the prepare or check watcher - they have no
1493parameters of any kind. There are <code>ev_prepare_set</code> and <code>ev_check_set</code> 1493parameters of any kind. There are <code>ev_prepare_set</code> and <code>ev_check_set</code>
1494macros, but using them is utterly, utterly and completely pointless.</p> 1494macros, but using them is utterly, utterly and completely pointless.</p>
1495 </dd> 1495 </dd>
1496</dl> 1496</dl>
1497<p>Example: To include a library such as adns, you would add IO watchers 1497<p>There are a number of principal ways to embed other event loops or modules
1498and a timeout watcher in a prepare handler, as required by libadns, and 1498into libev. Here are some ideas on how to include libadns into libev
1499(there is a Perl module named <code>EV::ADNS</code> that does this, which you could
1500use for an actually working example. Another Perl module named <code>EV::Glib</code>
1501embeds a Glib main context into libev, and finally, <code>Glib::EV</code> embeds EV
1502into the Glib event loop).</p>
1503<p>Method 1: Add IO watchers and a timeout watcher in a prepare handler,
1499in a check watcher, destroy them and call into libadns. What follows is 1504and in a check watcher, destroy them and call into libadns. What follows
1500pseudo-code only of course:</p> 1505is pseudo-code only of course. This requires you to either use a low
1506priority for the check watcher or use <code>ev_clear_pending</code> explicitly, as
1507the callbacks for the IO/timeout watchers might not have been called yet.</p>
1501<pre> static ev_io iow [nfd]; 1508<pre> static ev_io iow [nfd];
1502 static ev_timer tw; 1509 static ev_timer tw;
1503 1510
1504 static void 1511 static void
1505 io_cb (ev_loop *loop, ev_io *w, int revents) 1512 io_cb (ev_loop *loop, ev_io *w, int revents)
1506 { 1513 {
1507 // set the relevant poll flags
1508 // could also call adns_processreadable etc. here
1509 struct pollfd *fd = (struct pollfd *)w-&gt;data;
1510 if (revents &amp; EV_READ ) fd-&gt;revents |= fd-&gt;events &amp; POLLIN;
1511 if (revents &amp; EV_WRITE) fd-&gt;revents |= fd-&gt;events &amp; POLLOUT;
1512 } 1514 }
1513 1515
1514 // create io watchers for each fd and a timer before blocking 1516 // create io watchers for each fd and a timer before blocking
1515 static void 1517 static void
1516 adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents) 1518 adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents)
1522 1524
1523 /* the callback is illegal, but won't be called as we stop during check */ 1525 /* the callback is illegal, but won't be called as we stop during check */
1524 ev_timer_init (&amp;tw, 0, timeout * 1e-3); 1526 ev_timer_init (&amp;tw, 0, timeout * 1e-3);
1525 ev_timer_start (loop, &amp;tw); 1527 ev_timer_start (loop, &amp;tw);
1526 1528
1527 // create on ev_io per pollfd 1529 // create one ev_io per pollfd
1528 for (int i = 0; i &lt; nfd; ++i) 1530 for (int i = 0; i &lt; nfd; ++i)
1529 { 1531 {
1530 ev_io_init (iow + i, io_cb, fds [i].fd, 1532 ev_io_init (iow + i, io_cb, fds [i].fd,
1531 ((fds [i].events &amp; POLLIN ? EV_READ : 0) 1533 ((fds [i].events &amp; POLLIN ? EV_READ : 0)
1532 | (fds [i].events &amp; POLLOUT ? EV_WRITE : 0))); 1534 | (fds [i].events &amp; POLLOUT ? EV_WRITE : 0)));
1533 1535
1534 fds [i].revents = 0; 1536 fds [i].revents = 0;
1535 iow [i].data = fds + i;
1536 ev_io_start (loop, iow + i); 1537 ev_io_start (loop, iow + i);
1537 } 1538 }
1538 } 1539 }
1539 1540
1540 // stop all watchers after blocking 1541 // stop all watchers after blocking
1542 adns_check_cb (ev_loop *loop, ev_check *w, int revents) 1543 adns_check_cb (ev_loop *loop, ev_check *w, int revents)
1543 { 1544 {
1544 ev_timer_stop (loop, &amp;tw); 1545 ev_timer_stop (loop, &amp;tw);
1545 1546
1546 for (int i = 0; i &lt; nfd; ++i) 1547 for (int i = 0; i &lt; nfd; ++i)
1548 {
1549 // set the relevant poll flags
1550 // could also call adns_processreadable etc. here
1551 struct pollfd *fd = fds + i;
1552 int revents = ev_clear_pending (iow + i);
1553 if (revents &amp; EV_READ ) fd-&gt;revents |= fd-&gt;events &amp; POLLIN;
1554 if (revents &amp; EV_WRITE) fd-&gt;revents |= fd-&gt;events &amp; POLLOUT;
1555
1556 // now stop the watcher
1547 ev_io_stop (loop, iow + i); 1557 ev_io_stop (loop, iow + i);
1558 }
1548 1559
1549 adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop)); 1560 adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
1561 }
1562
1563</pre>
1564<p>Method 2: This would be just like method 1, but you run <code>adns_afterpoll</code>
1565in the prepare watcher and would dispose of the check watcher.</p>
1566<p>Method 3: If the module to be embedded supports explicit event
1567notification (adns does), you can also make use of the actual watcher
1568callbacks, and only destroy/create the watchers in the prepare watcher.</p>
1569<pre> static void
1570 timer_cb (EV_P_ ev_timer *w, int revents)
1571 {
1572 adns_state ads = (adns_state)w-&gt;data;
1573 update_now (EV_A);
1574
1575 adns_processtimeouts (ads, &amp;tv_now);
1576 }
1577
1578 static void
1579 io_cb (EV_P_ ev_io *w, int revents)
1580 {
1581 adns_state ads = (adns_state)w-&gt;data;
1582 update_now (EV_A);
1583
1584 if (revents &amp; EV_READ ) adns_processreadable (ads, w-&gt;fd, &amp;tv_now);
1585 if (revents &amp; EV_WRITE) adns_processwriteable (ads, w-&gt;fd, &amp;tv_now);
1586 }
1587
1588 // do not ever call adns_afterpoll
1589
1590</pre>
1591<p>Method 4: Do not use a prepare or check watcher because the module you
1592want to embed is too inflexible to support it. Instead, youc na override
1593their poll function. The drawback with this solution is that the main
1594loop is now no longer controllable by EV. The <code>Glib::EV</code> module does
1595this.</p>
1596<pre> static gint
1597 event_poll_func (GPollFD *fds, guint nfds, gint timeout)
1598 {
1599 int got_events = 0;
1600
1601 for (n = 0; n &lt; nfds; ++n)
1602 // create/start io watcher that sets the relevant bits in fds[n] and increment got_events
1603
1604 if (timeout &gt;= 0)
1605 // create/start timer
1606
1607 // poll
1608 ev_loop (EV_A_ 0);
1609
1610 // stop timer again
1611 if (timeout &gt;= 0)
1612 ev_timer_stop (EV_A_ &amp;to);
1613
1614 // stop io watchers again - their callbacks should have set
1615 for (n = 0; n &lt; nfds; ++n)
1616 ev_io_stop (EV_A_ iow [n]);
1617
1618 return got_events;
1550 } 1619 }
1551 1620
1552 1621
1553 1622
1554 1623

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines