master
Marc Alexander Lehmann 2007-11-27 10:59:10 +00:00
parent 87f398a731
commit b2a7836d18
8 changed files with 378 additions and 18 deletions

5
ev++.h
View File

@ -52,10 +52,13 @@ namespace ev {
TIMEOUT = EV_TIMEOUT,
PERIODIC = EV_PERIODIC,
SIGNAL = EV_SIGNAL,
CHILD = EV_CHILD,
STAT = EV_STAT,
IDLE = EV_IDLE,
CHECK = EV_CHECK,
PREPARE = EV_PREPARE,
CHILD = EV_CHILD,
FORK = EV_FORK,
EMBED = EV_EMBED,
ERROR = EV_ERROR,
};

93
ev.3
View File

@ -709,6 +709,15 @@ received events. Callbacks of both watcher types can start and stop as
many watchers as they want, and all of them will be taken into account
(for example, a \f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep
\&\f(CW\*(C`ev_loop\*(C'\fR from blocking).
.ie n .IP """EV_EMBED""" 4
.el .IP "\f(CWEV_EMBED\fR" 4
.IX Item "EV_EMBED"
The embedded event loop specified in the \f(CW\*(C`ev_embed\*(C'\fR watcher needs attention.
.ie n .IP """EV_FORK""" 4
.el .IP "\f(CWEV_FORK\fR" 4
.IX Item "EV_FORK"
The event loop has been resumed in the child process after fork (see
\&\f(CW\*(C`ev_fork\*(C'\fR).
.ie n .IP """EV_ERROR""" 4
.el .IP "\f(CWEV_ERROR\fR" 4
.IX Item "EV_ERROR"
@ -1615,6 +1624,21 @@ apropriate way for embedded loops.
.IP "struct ev_loop *loop [read\-only]" 4
.IX Item "struct ev_loop *loop [read-only]"
The embedded event loop.
.ie n .Sh """ev_fork"" \- the audacity to resume the event loop after a fork"
.el .Sh "\f(CWev_fork\fP \- the audacity to resume the event loop after a fork"
.IX Subsection "ev_fork - the audacity to resume the event loop after a fork"
Fork watchers are called when a \f(CW\*(C`fork ()\*(C'\fR was detected (usually because
whoever is a good citizen cared to tell libev about it by calling
\&\f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the
event loop blocks next and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called,
and only in the child after the fork. If whoever good citizen calling
\&\f(CW\*(C`ev_default_fork\*(C'\fR cheats and calls it in the wrong process, the fork
handlers will be invoked, too, of course.
.IP "ev_fork_init (ev_signal *, callback)" 4
.IX Item "ev_fork_init (ev_signal *, callback)"
Initialises and configures the fork watcher \- it has no parameters of any
kind. There is a \f(CW\*(C`ev_fork_set\*(C'\fR macro, but using it is utterly pointless,
believe me.
.SH "OTHER FUNCTIONS"
.IX Header "OTHER FUNCTIONS"
There are some other functions of possible interest. Described. Here. Now.
@ -1794,6 +1818,71 @@ the constructor.
\& io.start (fd, ev::READ);
\& }
.Ve
.SH "MACRO MAGIC"
.IX Header "MACRO MAGIC"
Libev can be compiled with a variety of options, the most fundemantal is
\&\f(CW\*(C`EV_MULTIPLICITY\*(C'\fR. This option determines wether (most) functions and
callbacks have an initial \f(CW\*(C`struct ev_loop *\*(C'\fR argument.
.PP
To make it easier to write programs that cope with either variant, the
following macros are defined:
.ie n .IP """EV_A""\fR, \f(CW""EV_A_""" 4
.el .IP "\f(CWEV_A\fR, \f(CWEV_A_\fR" 4
.IX Item "EV_A, EV_A_"
This provides the loop \fIargument\fR for functions, if one is required (\*(L"ev
loop argument\*(R"). The \f(CW\*(C`EV_A\*(C'\fR form is used when this is the sole argument,
\&\f(CW\*(C`EV_A_\*(C'\fR is used when other arguments are following. Example:
.Sp
.Vb 3
\& ev_unref (EV_A);
\& ev_timer_add (EV_A_ watcher);
\& ev_loop (EV_A_ 0);
.Ve
.Sp
It assumes the variable \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR is in scope,
which is often provided by the following macro.
.ie n .IP """EV_P""\fR, \f(CW""EV_P_""" 4
.el .IP "\f(CWEV_P\fR, \f(CWEV_P_\fR" 4
.IX Item "EV_P, EV_P_"
This provides the loop \fIparameter\fR for functions, if one is required (\*(L"ev
loop parameter\*(R"). The \f(CW\*(C`EV_P\*(C'\fR form is used when this is the sole parameter,
\&\f(CW\*(C`EV_P_\*(C'\fR is used when other parameters are following. Example:
.Sp
.Vb 2
\& // this is how ev_unref is being declared
\& static void ev_unref (EV_P);
.Ve
.Sp
.Vb 2
\& // this is how you can declare your typical callback
\& static void cb (EV_P_ ev_timer *w, int revents)
.Ve
.Sp
It declares a parameter \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR, quite
suitable for use with \f(CW\*(C`EV_A\*(C'\fR.
.ie n .IP """EV_DEFAULT""\fR, \f(CW""EV_DEFAULT_""" 4
.el .IP "\f(CWEV_DEFAULT\fR, \f(CWEV_DEFAULT_\fR" 4
.IX Item "EV_DEFAULT, EV_DEFAULT_"
Similar to the other two macros, this gives you the value of the default
loop, if multiple loops are supported (\*(L"ev loop default\*(R").
.PP
Example: Declare and initialise a check watcher, working regardless of
wether multiple loops are supported or not.
.PP
.Vb 5
\& static void
\& check_cb (EV_P_ ev_timer *w, int revents)
\& {
\& ev_check_stop (EV_A_ w);
\& }
.Ve
.PP
.Vb 4
\& ev_check check;
\& ev_check_init (&check, check_cb);
\& ev_check_start (EV_DEFAULT_ &check);
\& ev_loop (EV_DEFAULT_ 0);
.Ve
.SH "EMBEDDING"
.IX Header "EMBEDDING"
Libev can (and often is) directly embedded into host
@ -2022,6 +2111,10 @@ defined to be \f(CW0\fR, then they are not.
.IX Item "EV_STAT_ENABLE"
If undefined or defined to be \f(CW1\fR, then stat watchers are supported. If
defined to be \f(CW0\fR, then they are not.
.IP "\s-1EV_FORK_ENABLE\s0" 4
.IX Item "EV_FORK_ENABLE"
If undefined or defined to be \f(CW1\fR, then fork watchers are supported. If
defined to be \f(CW0\fR, then they are not.
.IP "\s-1EV_MINIMAL\s0" 4
.IX Item "EV_MINIMAL"
If you need to shave off some kilobytes of code at the expense of some

37
ev.c
View File

@ -1278,6 +1278,14 @@ ev_loop (EV_P_ int flags)
while (activecnt)
{
/* we might have forked, so reify kernel state if necessary */
if (expect_false (postfork))
if (forkcnt)
{
queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);
call_pending (EV_A);
}
/* queue check watchers (and execute them) */
if (expect_false (preparecnt))
{
@ -1829,6 +1837,35 @@ ev_embed_stop (EV_P_ ev_embed *w)
}
#endif
#if EV_FORK_ENABLE
void
ev_fork_start (EV_P_ ev_fork *w)
{
if (expect_false (ev_is_active (w)))
return;
ev_start (EV_A_ (W)w, ++forkcnt);
array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
forks [forkcnt - 1] = w;
}
void
ev_fork_stop (EV_P_ ev_fork *w)
{
ev_clear_pending (EV_A_ (W)w);
if (expect_false (!ev_is_active (w)))
return;
{
int active = ((W)w)->active;
forks [active - 1] = forks [--forkcnt];
((W)forks [active - 1])->active = active;
}
ev_stop (EV_A_ (W)w);
}
#endif
/*****************************************************************************/
struct ev_once

45
ev.h
View File

@ -56,6 +56,10 @@ typedef double ev_tstamp;
# define EV_STAT_ENABLE 1
#endif
#ifndef EV_FORK_ENABLE
# define EV_FORK_ENABLE 1
#endif
#ifndef EV_EMBED_ENABLE
# define EV_EMBED_ENABLE 1
#endif
@ -73,15 +77,15 @@ struct ev_loop;
# define EV_P_ EV_P,
# define EV_A loop
# define EV_A_ EV_A,
# define EV_DEFAULT_A ev_default_loop (0)
# define EV_DEFAULT_A_ EV_DEFAULT_A,
# define EV_DEFAULT ev_default_loop (0)
# define EV_DEFAULT_ EV_DEFAULT,
#else
# define EV_P void
# define EV_P_
# define EV_A
# define EV_A_
# define EV_DEFAULT_A
# define EV_DEFAULT_A_
# define EV_DEFAULT
# define EV_DEFAULT_
# undef EV_EMBED_ENABLE
#endif
@ -94,12 +98,13 @@ struct ev_loop;
#define EV_TIMEOUT 0x00000100L /* timer timed out */
#define EV_PERIODIC 0x00000200L /* periodic timer timed out */
#define EV_SIGNAL 0x00000400L /* signal was received */
#define EV_IDLE 0x00000800L /* event loop is idling */
#define EV_PREPARE 0x00001000L /* event loop about to poll */
#define EV_CHECK 0x00002000L /* event loop finished poll */
#define EV_CHILD 0x00004000L /* child/pid had status change */
#define EV_EMBED 0x00008000L /* embedded event loop needs sweep */
#define EV_STAT 0x00010000L /* stat data changed */
#define EV_CHILD 0x00000800L /* child/pid had status change */
#define EV_STAT 0x00001000L /* stat data changed */
#define EV_IDLE 0x00002000L /* event loop is idling */
#define EV_PREPARE 0x00004000L /* event loop about to poll */
#define EV_CHECK 0x00008000L /* event loop finished poll */
#define EV_EMBED 0x00010000L /* embedded event loop needs sweep */
#define EV_FORK 0x00020000L /* event loop resumed in child */
#define EV_ERROR 0x80000000L /* sent when an error occurs */
/* can be used to add custom fields to all watchers, while losing binary compatibility */
@ -255,6 +260,14 @@ typedef struct ev_check
EV_WATCHER (ev_check)
} ev_check;
#if EV_FORK_ENABLE
/* the callback gets invoked before check in the child process when a fork was detected */
typedef struct ev_fork
{
EV_WATCHER (ev_fork)
} ev_fork;
#endif
#if EV_EMBED_ENABLE
/* used to embed an event loop inside another */
/* the callback gets invoked when the event loop has handled events, and can be 0 */
@ -276,6 +289,7 @@ union ev_any_watcher
struct ev_io io;
struct ev_timer timer;
struct ev_periodic periodic;
struct ev_signal signal;
struct ev_child child;
#if EV_STAT_ENABLE
struct ev_stat stat;
@ -283,7 +297,9 @@ union ev_any_watcher
struct ev_idle idle;
struct ev_prepare prepare;
struct ev_check check;
struct ev_signal signal;
#if EV_FORK_ENABLE
struct ev_fork fork;
#endif
#if EV_EMBED_ENABLE
struct ev_embed embed;
#endif
@ -413,6 +429,7 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_embed_set(ev,loop_) do { (ev)->loop = (loop_); } while (0)
#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
@ -424,6 +441,7 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
#define ev_embed_init(ev,cb,loop) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(loop)); } while (0)
#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
@ -483,6 +501,11 @@ void ev_prepare_stop (EV_P_ ev_prepare *w);
void ev_check_start (EV_P_ ev_check *w);
void ev_check_stop (EV_P_ ev_check *w);
# if EV_FORK_ENABLE
void ev_fork_start (EV_P_ ev_fork *w);
void ev_fork_stop (EV_P_ ev_fork *w);
# endif
# if EV_EMBED_ENABLE
/* only supported when loop to be embedded is in fact embeddable */
void ev_embed_start (EV_P_ ev_embed *w);

109
ev.html
View File

@ -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="created" content="Tue Nov 27 09:20:40 2007" />
<meta name="created" content="Tue Nov 27 11:59:06 2007" />
<meta name="generator" content="Pod::Xhtml 1.57" />
<link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
<body>
@ -37,11 +37,13 @@
<li><a href="#code_ev_idle_code_when_you_ve_got_no"><code>ev_idle</code> - when you've got nothing better to do...</a></li>
<li><a href="#code_ev_prepare_code_and_code_ev_che"><code>ev_prepare</code> and <code>ev_check</code> - customise your event loop!</a></li>
<li><a href="#code_ev_embed_code_when_one_backend_"><code>ev_embed</code> - when one backend isn't enough...</a></li>
<li><a href="#code_ev_fork_code_the_audacity_to_re"><code>ev_fork</code> - the audacity to resume the event loop after a fork</a></li>
</ul>
</li>
<li><a href="#OTHER_FUNCTIONS">OTHER FUNCTIONS</a></li>
<li><a href="#LIBEVENT_EMULATION">LIBEVENT EMULATION</a></li>
<li><a href="#C_SUPPORT">C++ SUPPORT</a></li>
<li><a href="#MACRO_MAGIC">MACRO MAGIC</a></li>
<li><a href="#EMBEDDING">EMBEDDING</a>
<ul><li><a href="#FILESETS">FILESETS</a>
<ul><li><a href="#CORE_EVENT_LOOP">CORE EVENT LOOP</a></li>
@ -116,10 +118,6 @@ called <code>ev_tstamp</code>, which is what you should use too. It usually alia
to the <code>double</code> type in C, and when you need to do any calculations on
it, you should treat it as such.</p>
</div>
<h1 id="GLOBAL_FUNCTIONS">GLOBAL FUNCTIONS</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="GLOBAL_FUNCTIONS_CONTENT">
@ -607,6 +605,15 @@ received events. Callbacks of both watcher types can start and stop as
many watchers as they want, and all of them will be taken into account
(for example, a <code>ev_prepare</code> watcher might start an idle watcher to keep
<code>ev_loop</code> from blocking).</p>
</dd>
<dt><code>EV_EMBED</code></dt>
<dd>
<p>The embedded event loop specified in the <code>ev_embed</code> watcher needs attention.</p>
</dd>
<dt><code>EV_FORK</code></dt>
<dd>
<p>The event loop has been resumed in the child process after fork (see
<code>ev_fork</code>).</p>
</dd>
<dt><code>EV_ERROR</code></dt>
<dd>
@ -1481,6 +1488,29 @@ apropriate way for embedded loops.</p>
</div>
<h2 id="code_ev_fork_code_the_audacity_to_re"><code>ev_fork</code> - the audacity to resume the event loop after a fork</h2>
<div id="code_ev_fork_code_the_audacity_to_re-2">
<p>Fork watchers are called when a <code>fork ()</code> was detected (usually because
whoever is a good citizen cared to tell libev about it by calling
<code>ev_default_fork</code> or <code>ev_loop_fork</code>). The invocation is done before the
event loop blocks next and before <code>ev_check</code> watchers are being called,
and only in the child after the fork. If whoever good citizen calling
<code>ev_default_fork</code> cheats and calls it in the wrong process, the fork
handlers will be invoked, too, of course.</p>
<dl>
<dt>ev_fork_init (ev_signal *, callback)</dt>
<dd>
<p>Initialises and configures the fork watcher - it has no parameters of any
kind. There is a <code>ev_fork_set</code> macro, but using it is utterly pointless,
believe me.</p>
</dd>
</dl>
</div>
<h1 id="OTHER_FUNCTIONS">OTHER FUNCTIONS</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="OTHER_FUNCTIONS_CONTENT">
@ -1658,6 +1688,70 @@ the constructor.</p>
io.start (fd, ev::READ);
}
</pre>
</div>
<h1 id="MACRO_MAGIC">MACRO MAGIC</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="MACRO_MAGIC_CONTENT">
<p>Libev can be compiled with a variety of options, the most fundemantal is
<code>EV_MULTIPLICITY</code>. This option determines wether (most) functions and
callbacks have an initial <code>struct ev_loop *</code> argument.</p>
<p>To make it easier to write programs that cope with either variant, the
following macros are defined:</p>
<dl>
<dt><code>EV_A</code>, <code>EV_A_</code></dt>
<dd>
<p>This provides the loop <i>argument</i> for functions, if one is required (&quot;ev
loop argument&quot;). The <code>EV_A</code> form is used when this is the sole argument,
<code>EV_A_</code> is used when other arguments are following. Example:</p>
<pre> ev_unref (EV_A);
ev_timer_add (EV_A_ watcher);
ev_loop (EV_A_ 0);
</pre>
<p>It assumes the variable <code>loop</code> of type <code>struct ev_loop *</code> is in scope,
which is often provided by the following macro.</p>
</dd>
<dt><code>EV_P</code>, <code>EV_P_</code></dt>
<dd>
<p>This provides the loop <i>parameter</i> for functions, if one is required (&quot;ev
loop parameter&quot;). The <code>EV_P</code> form is used when this is the sole parameter,
<code>EV_P_</code> is used when other parameters are following. Example:</p>
<pre> // this is how ev_unref is being declared
static void ev_unref (EV_P);
// this is how you can declare your typical callback
static void cb (EV_P_ ev_timer *w, int revents)
</pre>
<p>It declares a parameter <code>loop</code> of type <code>struct ev_loop *</code>, quite
suitable for use with <code>EV_A</code>.</p>
</dd>
<dt><code>EV_DEFAULT</code>, <code>EV_DEFAULT_</code></dt>
<dd>
<p>Similar to the other two macros, this gives you the value of the default
loop, if multiple loops are supported (&quot;ev loop default&quot;).</p>
</dd>
</dl>
<p>Example: Declare and initialise a check watcher, working regardless of
wether multiple loops are supported or not.</p>
<pre> static void
check_cb (EV_P_ ev_timer *w, int revents)
{
ev_check_stop (EV_A_ w);
}
ev_check check;
ev_check_init (&amp;check, check_cb);
ev_check_start (EV_DEFAULT_ &amp;check);
ev_loop (EV_DEFAULT_ 0);
</pre>
</div>
@ -1891,6 +1985,11 @@ defined to be <code>0</code>, then they are not.</p>
<dt>EV_STAT_ENABLE</dt>
<dd>
<p>If undefined or defined to be <code>1</code>, then stat watchers are supported. If
defined to be <code>0</code>, then they are not.</p>
</dd>
<dt>EV_FORK_ENABLE</dt>
<dd>
<p>If undefined or defined to be <code>1</code>, then fork watchers are supported. If
defined to be <code>0</code>, then they are not.</p>
</dd>
<dt>EV_MINIMAL</dt>

98
ev.pod
View File

@ -50,7 +50,6 @@ called C<ev_tstamp>, which is what you should use too. It usually aliases
to the C<double> type in C, and when you need to do any calculations on
it, you should treat it as such.
=head1 GLOBAL FUNCTIONS
These functions can be called anytime, even before initialising the
@ -567,6 +566,15 @@ many watchers as they want, and all of them will be taken into account
(for example, a C<ev_prepare> watcher might start an idle watcher to keep
C<ev_loop> from blocking).
=item C<EV_EMBED>
The embedded event loop specified in the C<ev_embed> watcher needs attention.
=item C<EV_FORK>
The event loop has been resumed in the child process after fork (see
C<ev_fork>).
=item C<EV_ERROR>
An unspecified error has occured, the watcher has been stopped. This might
@ -1472,6 +1480,27 @@ The embedded event loop.
=back
=head2 C<ev_fork> - the audacity to resume the event loop after a fork
Fork watchers are called when a C<fork ()> was detected (usually because
whoever is a good citizen cared to tell libev about it by calling
C<ev_default_fork> or C<ev_loop_fork>). The invocation is done before the
event loop blocks next and before C<ev_check> watchers are being called,
and only in the child after the fork. If whoever good citizen calling
C<ev_default_fork> cheats and calls it in the wrong process, the fork
handlers will be invoked, too, of course.
=over 4
=item ev_fork_init (ev_signal *, callback)
Initialises and configures the fork watcher - it has no parameters of any
kind. There is a C<ev_fork_set> macro, but using it is utterly pointless,
believe me.
=back
=head1 OTHER FUNCTIONS
There are some other functions of possible interest. Described. Here. Now.
@ -1666,6 +1695,68 @@ the constructor.
io.start (fd, ev::READ);
}
=head1 MACRO MAGIC
Libev can be compiled with a variety of options, the most fundemantal is
C<EV_MULTIPLICITY>. This option determines wether (most) functions and
callbacks have an initial C<struct ev_loop *> argument.
To make it easier to write programs that cope with either variant, the
following macros are defined:
=over 4
=item C<EV_A>, C<EV_A_>
This provides the loop I<argument> for functions, if one is required ("ev
loop argument"). The C<EV_A> form is used when this is the sole argument,
C<EV_A_> is used when other arguments are following. Example:
ev_unref (EV_A);
ev_timer_add (EV_A_ watcher);
ev_loop (EV_A_ 0);
It assumes the variable C<loop> of type C<struct ev_loop *> is in scope,
which is often provided by the following macro.
=item C<EV_P>, C<EV_P_>
This provides the loop I<parameter> for functions, if one is required ("ev
loop parameter"). The C<EV_P> form is used when this is the sole parameter,
C<EV_P_> is used when other parameters are following. Example:
// this is how ev_unref is being declared
static void ev_unref (EV_P);
// this is how you can declare your typical callback
static void cb (EV_P_ ev_timer *w, int revents)
It declares a parameter C<loop> of type C<struct ev_loop *>, quite
suitable for use with C<EV_A>.
=item C<EV_DEFAULT>, C<EV_DEFAULT_>
Similar to the other two macros, this gives you the value of the default
loop, if multiple loops are supported ("ev loop default").
=back
Example: Declare and initialise a check watcher, working regardless of
wether multiple loops are supported or not.
static void
check_cb (EV_P_ ev_timer *w, int revents)
{
ev_check_stop (EV_A_ w);
}
ev_check check;
ev_check_init (&check, check_cb);
ev_check_start (EV_DEFAULT_ &check);
ev_loop (EV_DEFAULT_ 0);
=head1 EMBEDDING
Libev can (and often is) directly embedded into host
@ -1897,6 +1988,11 @@ defined to be C<0>, then they are not.
If undefined or defined to be C<1>, then stat watchers are supported. If
defined to be C<0>, then they are not.
=item EV_FORK_ENABLE
If undefined or defined to be C<1>, then fork watchers are supported. If
defined to be C<0>, then they are not.
=item EV_MINIMAL
If you need to shave off some kilobytes of code at the expense of some

View File

@ -80,5 +80,11 @@ VARx(struct ev_check **, checks)
VARx(int, checkmax)
VARx(int, checkcnt)
#if EV_FORK_ENABLE || EV_GENWRAP
VARx(struct ev_fork **, forks)
VARx(int, forkmax)
VARx(int, forkcnt)
#endif
#undef VARx

View File

@ -51,3 +51,6 @@
#define checks ((loop)->checks)
#define checkmax ((loop)->checkmax)
#define checkcnt ((loop)->checkcnt)
#define forks ((loop)->forks)
#define forkmax ((loop)->forkmax)
#define forkcnt ((loop)->forkcnt)