mirror of /home/gitosis/repositories/libev.git
*** empty log message ***
This commit is contained in:
parent
78fc327db0
commit
883b1688c6
127
ev.3
127
ev.3
|
@ -1646,25 +1646,28 @@ Initialises and configures the prepare or check watcher \- they have no
|
|||
parameters of any kind. There are \f(CW\*(C`ev_prepare_set\*(C'\fR and \f(CW\*(C`ev_check_set\*(C'\fR
|
||||
macros, but using them is utterly, utterly and completely pointless.
|
||||
.PP
|
||||
Example: To include a library such as adns, you would add \s-1IO\s0 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:
|
||||
There are a number of principal ways to embed other event loops or modules
|
||||
into libev. Here are some ideas on how to include libadns into libev
|
||||
(there is a Perl module named \f(CW\*(C`EV::ADNS\*(C'\fR that does this, which you could
|
||||
use for an actually working example. Another Perl module named \f(CW\*(C`EV::Glib\*(C'\fR
|
||||
embeds a Glib main context into libev, and finally, \f(CW\*(C`Glib::EV\*(C'\fR embeds \s-1EV\s0
|
||||
into the Glib event loop).
|
||||
.PP
|
||||
Method 1: Add \s-1IO\s0 watchers and a timeout watcher in a prepare handler,
|
||||
and in a check watcher, destroy them and call into libadns. What follows
|
||||
is pseudo-code only of course. This requires you to either use a low
|
||||
priority for the check watcher or use \f(CW\*(C`ev_clear_pending\*(C'\fR explicitly, as
|
||||
the callbacks for the IO/timeout watchers might not have been called yet.
|
||||
.PP
|
||||
.Vb 2
|
||||
\& static ev_io iow [nfd];
|
||||
\& static ev_timer tw;
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 9
|
||||
.Vb 4
|
||||
\& 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->data;
|
||||
\& if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
\& if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
\& }
|
||||
.Ve
|
||||
.PP
|
||||
|
@ -1686,7 +1689,7 @@ pseudo-code only of course:
|
|||
.Ve
|
||||
.PP
|
||||
.Vb 6
|
||||
\& // create on ev_io per pollfd
|
||||
\& // create one ev_io per pollfd
|
||||
\& for (int i = 0; i < nfd; ++i)
|
||||
\& {
|
||||
\& ev_io_init (iow + i, io_cb, fds [i].fd,
|
||||
|
@ -1694,9 +1697,8 @@ pseudo-code only of course:
|
|||
\& | (fds [i].events & POLLOUT ? EV_WRITE : 0)));
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 5
|
||||
.Vb 4
|
||||
\& fds [i].revents = 0;
|
||||
\& iow [i].data = fds + i;
|
||||
\& ev_io_start (loop, iow + i);
|
||||
\& }
|
||||
\& }
|
||||
|
@ -1710,15 +1712,110 @@ pseudo-code only of course:
|
|||
\& ev_timer_stop (loop, &tw);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
.Vb 8
|
||||
\& for (int i = 0; i < nfd; ++i)
|
||||
\& ev_io_stop (loop, iow + i);
|
||||
\& {
|
||||
\& // set the relevant poll flags
|
||||
\& // could also call adns_processreadable etc. here
|
||||
\& struct pollfd *fd = fds + i;
|
||||
\& int revents = ev_clear_pending (iow + i);
|
||||
\& if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
\& if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 3
|
||||
\& // now stop the watcher
|
||||
\& ev_io_stop (loop, iow + i);
|
||||
\& }
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
|
||||
\& }
|
||||
.Ve
|
||||
.PP
|
||||
Method 2: This would be just like method 1, but you run \f(CW\*(C`adns_afterpoll\*(C'\fR
|
||||
in the prepare watcher and would dispose of the check watcher.
|
||||
.PP
|
||||
Method 3: If the module to be embedded supports explicit event
|
||||
notification (adns does), you can also make use of the actual watcher
|
||||
callbacks, and only destroy/create the watchers in the prepare watcher.
|
||||
.PP
|
||||
.Vb 5
|
||||
\& static void
|
||||
\& timer_cb (EV_P_ ev_timer *w, int revents)
|
||||
\& {
|
||||
\& adns_state ads = (adns_state)w->data;
|
||||
\& update_now (EV_A);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& adns_processtimeouts (ads, &tv_now);
|
||||
\& }
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 5
|
||||
\& static void
|
||||
\& io_cb (EV_P_ ev_io *w, int revents)
|
||||
\& {
|
||||
\& adns_state ads = (adns_state)w->data;
|
||||
\& update_now (EV_A);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 3
|
||||
\& if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
|
||||
\& if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
|
||||
\& }
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 1
|
||||
\& // do not ever call adns_afterpoll
|
||||
.Ve
|
||||
.PP
|
||||
Method 4: Do not use a prepare or check watcher because the module you
|
||||
want to embed is too inflexible to support it. Instead, youc na override
|
||||
their poll function. The drawback with this solution is that the main
|
||||
loop is now no longer controllable by \s-1EV\s0. The \f(CW\*(C`Glib::EV\*(C'\fR module does
|
||||
this.
|
||||
.PP
|
||||
.Vb 4
|
||||
\& static gint
|
||||
\& event_poll_func (GPollFD *fds, guint nfds, gint timeout)
|
||||
\& {
|
||||
\& int got_events = 0;
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& for (n = 0; n < nfds; ++n)
|
||||
\& // create/start io watcher that sets the relevant bits in fds[n] and increment got_events
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& if (timeout >= 0)
|
||||
\& // create/start timer
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& // poll
|
||||
\& ev_loop (EV_A_ 0);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 3
|
||||
\& // stop timer again
|
||||
\& if (timeout >= 0)
|
||||
\& ev_timer_stop (EV_A_ &to);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 3
|
||||
\& // stop io watchers again - their callbacks should have set
|
||||
\& for (n = 0; n < nfds; ++n)
|
||||
\& ev_io_stop (EV_A_ iow [n]);
|
||||
.Ve
|
||||
.PP
|
||||
.Vb 2
|
||||
\& return got_events;
|
||||
\& }
|
||||
.Ve
|
||||
.ie n .Sh """ev_embed"" \- when one backend isn't enough..."
|
||||
.el .Sh "\f(CWev_embed\fP \- when one backend isn't enough..."
|
||||
.IX Subsection "ev_embed - when one backend isn't enough..."
|
||||
|
|
95
ev.html
95
ev.html
|
@ -6,7 +6,7 @@
|
|||
<meta name="description" content="Pod documentation for libev" />
|
||||
<meta name="inputfile" content="<standard input>" />
|
||||
<meta name="outputfile" content="<standard output>" />
|
||||
<meta name="created" content="Sat Dec 8 15:31:35 2007" />
|
||||
<meta name="created" content="Sat Dec 8 16:30:24 2007" />
|
||||
<meta name="generator" content="Pod::Xhtml 1.57" />
|
||||
<link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
|
||||
<body>
|
||||
|
@ -1494,21 +1494,23 @@ 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>
|
||||
<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>
|
||||
<p>There are a number of principal ways to embed other event loops or modules
|
||||
into libev. Here are some ideas on how to include libadns into libev
|
||||
(there is a Perl module named <code>EV::ADNS</code> that does this, which you could
|
||||
use for an actually working example. Another Perl module named <code>EV::Glib</code>
|
||||
embeds a Glib main context into libev, and finally, <code>Glib::EV</code> embeds EV
|
||||
into the Glib event loop).</p>
|
||||
<p>Method 1: Add IO watchers and a timeout watcher in a prepare handler,
|
||||
and in a check watcher, destroy them and call into libadns. What follows
|
||||
is pseudo-code only of course. This requires you to either use a low
|
||||
priority for the check watcher or use <code>ev_clear_pending</code> explicitly, as
|
||||
the callbacks for the IO/timeout watchers might not have been called yet.</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->data;
|
||||
if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
}
|
||||
|
||||
// create io watchers for each fd and a timer before blocking
|
||||
|
@ -1524,7 +1526,7 @@ pseudo-code only of course:</p>
|
|||
ev_timer_init (&tw, 0, timeout * 1e-3);
|
||||
ev_timer_start (loop, &tw);
|
||||
|
||||
// create on ev_io per pollfd
|
||||
// create one ev_io per pollfd
|
||||
for (int i = 0; i < nfd; ++i)
|
||||
{
|
||||
ev_io_init (iow + i, io_cb, fds [i].fd,
|
||||
|
@ -1532,7 +1534,6 @@ pseudo-code only of course:</p>
|
|||
| (fds [i].events & POLLOUT ? EV_WRITE : 0)));
|
||||
|
||||
fds [i].revents = 0;
|
||||
iow [i].data = fds + i;
|
||||
ev_io_start (loop, iow + i);
|
||||
}
|
||||
}
|
||||
|
@ -1544,11 +1545,79 @@ pseudo-code only of course:</p>
|
|||
ev_timer_stop (loop, &tw);
|
||||
|
||||
for (int i = 0; i < nfd; ++i)
|
||||
ev_io_stop (loop, iow + i);
|
||||
{
|
||||
// set the relevant poll flags
|
||||
// could also call adns_processreadable etc. here
|
||||
struct pollfd *fd = fds + i;
|
||||
int revents = ev_clear_pending (iow + i);
|
||||
if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
|
||||
// now stop the watcher
|
||||
ev_io_stop (loop, iow + i);
|
||||
}
|
||||
|
||||
adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
|
||||
}
|
||||
|
||||
</pre>
|
||||
<p>Method 2: This would be just like method 1, but you run <code>adns_afterpoll</code>
|
||||
in the prepare watcher and would dispose of the check watcher.</p>
|
||||
<p>Method 3: If the module to be embedded supports explicit event
|
||||
notification (adns does), you can also make use of the actual watcher
|
||||
callbacks, and only destroy/create the watchers in the prepare watcher.</p>
|
||||
<pre> static void
|
||||
timer_cb (EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
adns_state ads = (adns_state)w->data;
|
||||
update_now (EV_A);
|
||||
|
||||
adns_processtimeouts (ads, &tv_now);
|
||||
}
|
||||
|
||||
static void
|
||||
io_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
adns_state ads = (adns_state)w->data;
|
||||
update_now (EV_A);
|
||||
|
||||
if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
|
||||
if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
|
||||
}
|
||||
|
||||
// do not ever call adns_afterpoll
|
||||
|
||||
</pre>
|
||||
<p>Method 4: Do not use a prepare or check watcher because the module you
|
||||
want to embed is too inflexible to support it. Instead, youc na override
|
||||
their poll function. The drawback with this solution is that the main
|
||||
loop is now no longer controllable by EV. The <code>Glib::EV</code> module does
|
||||
this.</p>
|
||||
<pre> static gint
|
||||
event_poll_func (GPollFD *fds, guint nfds, gint timeout)
|
||||
{
|
||||
int got_events = 0;
|
||||
|
||||
for (n = 0; n < nfds; ++n)
|
||||
// create/start io watcher that sets the relevant bits in fds[n] and increment got_events
|
||||
|
||||
if (timeout >= 0)
|
||||
// create/start timer
|
||||
|
||||
// poll
|
||||
ev_loop (EV_A_ 0);
|
||||
|
||||
// stop timer again
|
||||
if (timeout >= 0)
|
||||
ev_timer_stop (EV_A_ &to);
|
||||
|
||||
// stop io watchers again - their callbacks should have set
|
||||
for (n = 0; n < nfds; ++n)
|
||||
ev_io_stop (EV_A_ iow [n]);
|
||||
|
||||
return got_events;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
95
ev.pod
95
ev.pod
|
@ -1495,10 +1495,18 @@ macros, but using them is utterly, utterly and completely pointless.
|
|||
|
||||
=back
|
||||
|
||||
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:
|
||||
There are a number of principal ways to embed other event loops or modules
|
||||
into libev. Here are some ideas on how to include libadns into libev
|
||||
(there is a Perl module named C<EV::ADNS> that does this, which you could
|
||||
use for an actually working example. Another Perl module named C<EV::Glib>
|
||||
embeds a Glib main context into libev, and finally, C<Glib::EV> embeds EV
|
||||
into the Glib event loop).
|
||||
|
||||
Method 1: Add IO watchers and a timeout watcher in a prepare handler,
|
||||
and in a check watcher, destroy them and call into libadns. What follows
|
||||
is pseudo-code only of course. This requires you to either use a low
|
||||
priority for the check watcher or use C<ev_clear_pending> explicitly, as
|
||||
the callbacks for the IO/timeout watchers might not have been called yet.
|
||||
|
||||
static ev_io iow [nfd];
|
||||
static ev_timer tw;
|
||||
|
@ -1506,11 +1514,6 @@ pseudo-code only of course:
|
|||
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->data;
|
||||
if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
}
|
||||
|
||||
// create io watchers for each fd and a timer before blocking
|
||||
|
@ -1526,7 +1529,7 @@ pseudo-code only of course:
|
|||
ev_timer_init (&tw, 0, timeout * 1e-3);
|
||||
ev_timer_start (loop, &tw);
|
||||
|
||||
// create on ev_io per pollfd
|
||||
// create one ev_io per pollfd
|
||||
for (int i = 0; i < nfd; ++i)
|
||||
{
|
||||
ev_io_init (iow + i, io_cb, fds [i].fd,
|
||||
|
@ -1534,7 +1537,6 @@ pseudo-code only of course:
|
|||
| (fds [i].events & POLLOUT ? EV_WRITE : 0)));
|
||||
|
||||
fds [i].revents = 0;
|
||||
iow [i].data = fds + i;
|
||||
ev_io_start (loop, iow + i);
|
||||
}
|
||||
}
|
||||
|
@ -1546,11 +1548,80 @@ pseudo-code only of course:
|
|||
ev_timer_stop (loop, &tw);
|
||||
|
||||
for (int i = 0; i < nfd; ++i)
|
||||
ev_io_stop (loop, iow + i);
|
||||
{
|
||||
// set the relevant poll flags
|
||||
// could also call adns_processreadable etc. here
|
||||
struct pollfd *fd = fds + i;
|
||||
int revents = ev_clear_pending (iow + i);
|
||||
if (revents & EV_READ ) fd->revents |= fd->events & POLLIN;
|
||||
if (revents & EV_WRITE) fd->revents |= fd->events & POLLOUT;
|
||||
|
||||
// now stop the watcher
|
||||
ev_io_stop (loop, iow + i);
|
||||
}
|
||||
|
||||
adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop));
|
||||
}
|
||||
|
||||
Method 2: This would be just like method 1, but you run C<adns_afterpoll>
|
||||
in the prepare watcher and would dispose of the check watcher.
|
||||
|
||||
Method 3: If the module to be embedded supports explicit event
|
||||
notification (adns does), you can also make use of the actual watcher
|
||||
callbacks, and only destroy/create the watchers in the prepare watcher.
|
||||
|
||||
static void
|
||||
timer_cb (EV_P_ ev_timer *w, int revents)
|
||||
{
|
||||
adns_state ads = (adns_state)w->data;
|
||||
update_now (EV_A);
|
||||
|
||||
adns_processtimeouts (ads, &tv_now);
|
||||
}
|
||||
|
||||
static void
|
||||
io_cb (EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
adns_state ads = (adns_state)w->data;
|
||||
update_now (EV_A);
|
||||
|
||||
if (revents & EV_READ ) adns_processreadable (ads, w->fd, &tv_now);
|
||||
if (revents & EV_WRITE) adns_processwriteable (ads, w->fd, &tv_now);
|
||||
}
|
||||
|
||||
// do not ever call adns_afterpoll
|
||||
|
||||
Method 4: Do not use a prepare or check watcher because the module you
|
||||
want to embed is too inflexible to support it. Instead, youc na override
|
||||
their poll function. The drawback with this solution is that the main
|
||||
loop is now no longer controllable by EV. The C<Glib::EV> module does
|
||||
this.
|
||||
|
||||
static gint
|
||||
event_poll_func (GPollFD *fds, guint nfds, gint timeout)
|
||||
{
|
||||
int got_events = 0;
|
||||
|
||||
for (n = 0; n < nfds; ++n)
|
||||
// create/start io watcher that sets the relevant bits in fds[n] and increment got_events
|
||||
|
||||
if (timeout >= 0)
|
||||
// create/start timer
|
||||
|
||||
// poll
|
||||
ev_loop (EV_A_ 0);
|
||||
|
||||
// stop timer again
|
||||
if (timeout >= 0)
|
||||
ev_timer_stop (EV_A_ &to);
|
||||
|
||||
// stop io watchers again - their callbacks should have set
|
||||
for (n = 0; n < nfds; ++n)
|
||||
ev_io_stop (EV_A_ iow [n]);
|
||||
|
||||
return got_events;
|
||||
}
|
||||
|
||||
|
||||
=head2 C<ev_embed> - when one backend isn't enough...
|
||||
|
||||
|
|
Loading…
Reference in New Issue