--- libev/ev.pod 2012/05/04 20:47:27 1.411
+++ libev/ev.pod 2019/06/25 05:17:50 1.454
@@ -1,3 +1,5 @@
+=encoding utf-8
+
=head1 NAME
libev - a high performance full-featured event loop written in C
@@ -84,9 +86,9 @@
This manual tries to be very detailed, but unfortunately, this also makes
it very long. If you just want to know the basics of libev, I suggest
-reading L, then the L above and
-look up the missing functions in L and the C and
-C sections in L.
+reading L , then the L above and
+look up the missing functions in L and the C and
+C sections in L.
=head1 ABOUT LIBEV
@@ -105,10 +107,10 @@
=head2 FEATURES
-Libev supports C, C, the Linux-specific C, the
-BSD-specific C and the Solaris-specific event port mechanisms
-for file descriptor events (C), the Linux C interface
-(for C), Linux eventfd/signalfd (for faster and cleaner
+Libev supports C, C, the Linux-specific aio and C
+interfaces, the BSD-specific C and the Solaris-specific event port
+mechanisms for file descriptor events (C), the Linux C
+interface (for C), Linux eventfd/signalfd (for faster and cleaner
inter-thread wakeup (C)/signal handling (C)) relative
timers (C), absolute timers with customised rescheduling
(C), synchronous signals (C), process status
@@ -265,12 +267,32 @@
free some memory if it cannot allocate memory, to use a special allocator,
or even to sleep a while and retry until some memory is available.
+Example: The following is the C function that libev itself uses
+which should work with C and C functions of all kinds and
+is probably a good basis for your own implementation.
+
+ static void *
+ ev_realloc_emul (void *ptr, long size) EV_NOEXCEPT
+ {
+ if (size)
+ return realloc (ptr, size);
+
+ free (ptr);
+ return 0;
+ }
+
Example: Replace the libev allocator with one that waits a bit and then
-retries (example requires a standards-compliant C).
+retries.
static void *
persistent_realloc (void *ptr, size_t size)
{
+ if (!size)
+ {
+ free (ptr);
+ return 0;
+ }
+
for (;;)
{
void *newptr = realloc (ptr, size);
@@ -398,8 +420,10 @@
or setgid) then libev will I look at the environment variable
C. Otherwise (the default), this environment variable will
override the flags completely if it is found in the environment. This is
-useful to try out specific backends to test their performance, or to work
-around bugs.
+useful to try out specific backends to test their performance, to work
+around bugs, or to make libev threadsafe (accessing environment variables
+cannot be done in a threadsafe way, but usually it works if no other
+thread modifies them).
=item C
@@ -409,13 +433,14 @@
This works by calling C on every iteration of the loop,
and thus this might slow down your event loop if you do a lot of loop
iterations and little real work, but is usually not noticeable (on my
-GNU/Linux system for example, C is actually a simple 5-insn sequence
-without a system call and thus I fast, but my GNU/Linux system also has
-C which is even faster).
+GNU/Linux system for example, C is actually a simple 5-insn
+sequence without a system call and thus I fast, but my GNU/Linux
+system also has C which is even faster). (Update: glibc
+versions 2.25 apparently removed the C optimisation again).
The big advantage of this flag is that you can forget about fork (and
-forget about forgetting to tell libev about forking) when you use this
-flag.
+forget about forgetting to tell libev about forking, although you still
+have to ignore C) when you use this flag.
This flag setting cannot be overridden or specified in the C
environment variable.
@@ -488,7 +513,7 @@
=item C (value 4, Linux)
-Use the linux-specific epoll(7) interface (for both pre- and post-2.6.9
+Use the Linux-specific epoll(7) interface (for both pre- and post-2.6.9
kernels).
For few fds, this backend is a bit little slower than poll and select, but
@@ -544,22 +569,66 @@
the usage. So sad.
While nominally embeddable in other event loops, this feature is broken in
-all kernel versions tested so far.
+a lot of kernel revisions, but probably(!) works in current versions.
+
+This backend maps C and C in the same way as
+C.
+
+=item C (value 64, Linux)
+
+Use the Linux-specific Linux AIO (I C<< aio(7) >> but C<<
+io_submit(2) >>) event interface available in post-4.18 kernels (but libev
+only tries to use it in 4.19+).
+
+This is another Linux train wreck of an event interface.
+
+If this backend works for you (as of this writing, it was very
+experimental), it is the best event interface available on Linux and might
+be well worth enabling it - if it isn't available in your kernel this will
+be detected and this backend will be skipped.
+
+This backend can batch oneshot requests and supports a user-space ring
+buffer to receive events. It also doesn't suffer from most of the design
+problems of epoll (such as not being able to remove event sources from
+the epoll set), and generally sounds too good to be true. Because, this
+being the Linux kernel, of course it suffers from a whole new set of
+limitations, forcing you to fall back to epoll, inheriting all its design
+issues.
+
+For one, it is not easily embeddable (but probably could be done using
+an event fd at some extra overhead). It also is subject to a system wide
+limit that can be configured in F. If no AIO
+requests are left, this backend will be skipped during initialisation, and
+will switch to epoll when the loop is active.
+
+Most problematic in practice, however, is that not all file descriptors
+work with it. For example, in Linux 5.1, TCP sockets, pipes, event fds,
+files, F and many others are supported, but ttys do not work
+properly (a known bug that the kernel developers don't care about, see
+L ), so this is not
+(yet?) a generic event polling interface.
+
+Overall, it seems the Linux developers just don't want it to have a
+generic event handling mechanism other than C or C.
+
+To work around all these problem, the current version of libev uses its
+epoll backend as a fallback for file descriptor types that do not work. Or
+falls back completely to epoll if the kernel acts up.
This backend maps C and C in the same way as
C.
=item C (value 8, most BSD clones)
-Kqueue deserves special mention, as at the time of this writing, it
-was broken on all BSDs except NetBSD (usually it doesn't work reliably
-with anything but sockets and pipes, except on Darwin, where of course
-it's completely useless). Unlike epoll, however, whose brokenness
-is by design, these kqueue bugs can (and eventually will) be fixed
-without API changes to existing programs. For this reason it's not being
-"auto-detected" unless you explicitly specify it in the flags (i.e. using
-C) or libev was compiled on a known-to-be-good (-enough)
-system like NetBSD.
+Kqueue deserves special mention, as at the time this backend was
+implemented, it was broken on all BSDs except NetBSD (usually it doesn't
+work reliably with anything but sockets and pipes, except on Darwin,
+where of course it's completely useless). Unlike epoll, however, whose
+brokenness is by design, these kqueue bugs can be (and mostly have been)
+fixed without API changes to existing programs. For this reason it's not
+being "auto-detected" on all platforms unless you explicitly specify it
+in the flags (i.e. using C) or libev was compiled on a
+known-to-be-good (-enough) system like NetBSD.
You still can embed kqueue into a normal poll or select backend and use it
only for sockets (after having made sure that sockets work with kqueue on
@@ -570,8 +639,8 @@
course). While stopping, setting and starting an I/O watcher does never
cause an extra system call as with C, it still adds up to
two event changes per incident. Support for C is very bad (you
-might have to leak fd's on fork, but it's more sane than epoll) and it
-drops fds silently in similarly hard-to-detect cases
+might have to leak fds on fork, but it's more sane than epoll) and it
+drops fds silently in similarly hard-to-detect cases.
This backend usually performs well under most conditions.
@@ -655,6 +724,12 @@
struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE);
+Example: Similarly, on linux, you mgiht want to take advantage of the
+linux aio backend if possible, but fall back to something else if that
+isn't available.
+
+ struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_LINUXAIO);
+
=item ev_loop_destroy (loop)
Destroys an event loop object (frees all memory and kernel state
@@ -680,13 +755,17 @@
=item ev_loop_fork (loop)
-This function sets a flag that causes subsequent C iterations to
-reinitialise the kernel state for backends that have one. Despite the
-name, you can call it anytime, but it makes most sense after forking, in
-the child process. You I call it (or use C) in the
-child before resuming or calling C.
+This function sets a flag that causes subsequent C iterations
+to reinitialise the kernel state for backends that have one. Despite
+the name, you can call it anytime you are allowed to start or stop
+watchers (except inside an C callback), but it makes most
+sense after forking, in the child process. You I call it (or use
+C) in the child before resuming or calling C.
+
+In addition, if you want to reuse a loop (via this function or
+C), you I have to ignore C.
-Again, you I to call it on I loop that you want to re-use after
+Again, you I to call it on I loop that you want to re-use after
a fork, I. This is
because some kernel interfaces *cough* I *cough* do funny things
during fork.
@@ -766,7 +845,7 @@
very long time without entering the event loop, updating libev's idea of
the current time is a good idea.
-See also L in the C section.
+See also L in the C section.
=item ev_suspend (loop)
@@ -1348,7 +1427,7 @@
The default priority used by watchers when no priority has been set is
always C<0>, which is supposed to not be too high and not be too low :).
-See L, below, for a more thorough treatment of
+See L , below, for a more thorough treatment of
priorities.
=item ev_invoke (loop, ev_TYPE *watcher, int revents)
@@ -1383,7 +1462,7 @@
=back
-See also the L and L and L idioms.
=head2 WATCHER STATES
@@ -1395,7 +1474,7 @@
=over 4
-=item initialiased
+=item initialised
Before a watcher can be registered with the event loop it has to be
initialised. This can be done with a call to C, or calls to
@@ -1603,13 +1682,13 @@
=head3 The special problem of disappearing file descriptors
-Some backends (e.g. kqueue, epoll) need to be told about closing a file
-descriptor (either due to calling C explicitly or any other means,
-such as C). The reason is that you register interest in some file
-descriptor, but when it goes away, the operating system will silently drop
-this interest. If another file descriptor with the same number then is
-registered with libev, there is no efficient way to see that this is, in
-fact, a different file descriptor.
+Some backends (e.g. kqueue, epoll, linuxaio) need to be told about closing
+a file descriptor (either due to calling C explicitly or any other
+means, such as C). The reason is that you register interest in some
+file descriptor, but when it goes away, the operating system will silently
+drop this interest. If another file descriptor with the same number then
+is registered with libev, there is no efficient way to see that this is,
+in fact, a different file descriptor.
To avoid having to explicitly tell libev about such cases, libev follows
the following policy: Each time C is being called, libev
@@ -1668,9 +1747,10 @@
=head3 The special problem of fork
-Some backends (epoll, kqueue) do not support C at all or exhibit
-useless behaviour. Libev fully supports fork, but needs to be told about
-it in the child if you want to continue to use it in the child.
+Some backends (epoll, kqueue, probably linuxaio) do not support C
+at all or exhibit useless behaviour. Libev fully supports fork, but needs
+to be told about it in the child if you want to continue to use it in the
+child.
To support fork in your child processes, you have to call C after a fork in the child, enable C, or resort to
@@ -2026,13 +2106,15 @@
time. This is usually the right thing as this timestamp refers to the time
of the event triggering whatever timeout you are modifying/starting. If
you suspect event processing to be delayed and you I to base the
-timeout on the current time, use something like this to adjust for this:
+timeout on the current time, use something like the following to adjust
+for it:
- ev_timer_set (&timer, after + ev_now () - ev_time (), 0.);
+ ev_timer_set (&timer, after + (ev_time () - ev_now ()), 0.);
If the event loop is suspended for a long time, you can also force an
update of the time returned by C by calling C.
+()>, although that will push the event time of all outstanding events
+further into the future.
=head3 The special problem of unsynchronised clocks
@@ -2105,11 +2187,11 @@
=item ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)
-Configure the timer to trigger after C seconds. If C
-is C<0.>, then it will automatically be stopped once the timeout is
-reached. If it is positive, then the timer will automatically be
-configured to trigger again C seconds later, again, and again,
-until stopped manually.
+Configure the timer to trigger after C seconds (fractional and
+negative values are supported). If C is C<0.>, then it will
+automatically be stopped once the timeout is reached. If it is positive,
+then the timer will automatically be configured to trigger again C
+seconds later, again, and again, until stopped manually.
The timer itself will do a best-effort at avoiding drift, that is, if
you configure a timer to trigger every 10 seconds, then it will normally
@@ -2138,7 +2220,7 @@
=back
-This sounds a bit complicated, see L, above, for a
+This sounds a bit complicated, see L , above, for a
usage example.
=item ev_tstamp ev_timer_remaining (loop, ev_timer *)
@@ -2201,7 +2283,7 @@
Unlike C, periodic watchers are not based on real time (or
relative time, the physical time that passes) but on wall clock time
-(absolute time, the thing you can read on your calender or clock). The
+(absolute time, the thing you can read on your calendar or clock). The
difference is that wall clock time can run faster or slower than real
time, and time jumps are not uncommon (e.g. when you adjust your
wrist-watch).
@@ -2216,8 +2298,8 @@
C watchers can also be used to implement vastly more complex
timers, such as triggering an event on each "midnight, local time", or
-other complicated rules. This cannot be done with C watchers, as
-those cannot react to time jumps.
+other complicated rules. This cannot easily be done with C
+watchers, as those cannot react to time jumps.
As with timers, the callback is guaranteed to be invoked only when the
point in time where it is supposed to trigger has passed. If multiple
@@ -2313,10 +2395,28 @@
equal to the passed C value >>.
This can be used to create very complex timers, such as a timer that
-triggers on "next midnight, local time". To do this, you would calculate the
-next midnight after C and return the timestamp value for this. How
-you do this is, again, up to you (but it is not trivial, which is the main
-reason I omitted it as an example).
+triggers on "next midnight, local time". To do this, you would calculate
+the next midnight after C and return the timestamp value for
+this. Here is a (completely untested, no error checking) example on how to
+do this:
+
+ #include
+
+ static ev_tstamp
+ my_rescheduler (ev_periodic *w, ev_tstamp now)
+ {
+ time_t tnow = (time_t)now;
+ struct tm tm;
+ localtime_r (&tnow, &tm);
+
+ tm.tm_sec = tm.tm_min = tm.tm_hour = 0; // midnight current day
+ ++tm.tm_mday; // midnight next day
+
+ return mktime (&tm);
+ }
+
+Note: this code might run into trouble on days that have more then two
+midnights (beginning and end).
=back
@@ -2391,7 +2491,7 @@
ev_periodic_init (&hourly_tick, clock_cb,
fmod (ev_now (loop), 3600.), 3600., 0);
ev_periodic_start (loop, &hourly_tick);
-
+
=head2 C - signal me when a signal gets signalled!
@@ -2411,9 +2511,9 @@
C in both the default loop and another loop at the same time. At
the moment, C is permanently tied to the default loop.
-When the first watcher gets started will libev actually register something
-with the kernel (thus it coexists with your own signal handlers as long as
-you don't register any with libev for the same signal).
+Only after the first watcher for a signal is started will libev actually
+register something with the kernel. It thus coexists with your own signal
+handlers as long as you don't register any with libev for the same signal.
If possible and supported, libev will install its handlers with
C (or equivalent) behaviour enabled, so system calls should
@@ -2608,8 +2708,9 @@
This watches a file system path for attribute changes. That is, it calls
C on that path in regular intervals (or when the OS says it changed)
-and sees if it changed compared to the last time, invoking the callback if
-it did.
+and sees if it changed compared to the last time, invoking the callback
+if it did. Starting the watcher C's the file, so only changes that
+happen after the watcher has been started will be reported.
The path does not need to exist: changing from "path exists" to "path does
not exist" is a status change like any other. The condition "path does not
@@ -2860,7 +2961,7 @@
to do something on each event loop iteration - for example to balance load
between different connections.
-See L for a longer
+See L for a longer
example.
=head3 Watcher-Specific Functions and Data Members
@@ -2904,13 +3005,13 @@
prepare watchers get invoked before the process blocks and check watchers
afterwards.
-You I call C or similar functions that enter
-the current event loop from either C or C
-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 C, blocking,
-C so if you have one watcher of each kind they will always be
-called in pairs bracketing the blocking call.
+You I call C (or similar functions that enter the
+current event loop) or C from either C or
+C 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
+C, blocking, C so if you have one watcher of each
+kind they will always be called in pairs bracketing the blocking call.
Their main purpose is to integrate other event mechanisms into libev and
their use is somewhat advanced. They could be used, for example, to track
@@ -2964,7 +3065,6 @@
next event loop iteration. However, that isn't as soon as possible -
without external events, your C watcher will not be invoked.
-
This is where C watchers come in handy - all you need is a
single global idle watcher that is active as long as you have one active
C watcher. The C watcher makes sure the event loop
@@ -3180,7 +3280,7 @@
=item ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)
-=item ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)
+=item ev_embed_set (ev_embed *, struct ev_loop *embedded_loop)
Configures the watcher to embed the given loop, which must be
embeddable. If the callback is C<0>, then C will be
@@ -3211,7 +3311,7 @@
struct ev_loop *loop_hi = ev_default_init (0);
struct ev_loop *loop_lo = 0;
ev_embed embed;
-
+
// see if there is a chance of getting one that works
// (remember that a flags value of 0 means autodetection)
loop_lo = ev_embeddable_backends () & ev_recommended_backends ()
@@ -3235,7 +3335,7 @@
struct ev_loop *loop = ev_default_init (0);
struct ev_loop *loop_socket = 0;
ev_embed embed;
-
+
if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE)
if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE))
{
@@ -3253,15 +3353,15 @@
Fork watchers are called when a C was detected (usually because
whoever is a good citizen cared to tell libev about it by calling
-C or C). The invocation is done before the
-event loop blocks next and before C watchers are being called,
-and only in the child after the fork. If whoever good citizen calling
-C cheats and calls it in the wrong process, the fork
-handlers will be invoked, too, of course.
+C). The invocation is done before the event loop blocks next
+and before C watchers are being called, and only in the child
+after the fork. If whoever good citizen calling C cheats
+and calls it in the wrong process, the fork handlers will be invoked, too,
+of course.
=head3 The special problem of life after fork - how is it possible?
-Most uses of C consist of forking, then some simple calls to set
+Most uses of C consist of forking, then some simple calls to set
up/change the process environment, followed by a call to C. This
sequence should be handled by libev without any problems.
@@ -3509,7 +3609,7 @@
=over 4
-=item ev_once (loop, int fd, int events, ev_tstamp timeout, callback)
+=item ev_once (loop, int fd, int events, ev_tstamp timeout, callback, arg)
This function combines a simple timer and an I/O watcher, calls your
callback on whichever event happens first and automatically stops both
@@ -3661,9 +3761,9 @@
A common way around all these issues is to make sure that
C I returns before the callback is invoked. If
C immediately knows the result, it can artificially
-delay invoking the callback by e.g. using a C or C watcher
-for example, or more sneakily, by reusing an existing (stopped) watcher
-and pushing it into the pending queue:
+delay invoking the callback by using a C or C watcher for
+example, or more sneakily, by reusing an existing (stopped) watcher and
+pushing it into the pending queue:
ev_set_cb (watcher, callback);
ev_feed_event (EV_A_ watcher, 0);
@@ -3681,7 +3781,7 @@
main C call, but not the nested one (e.g. user clicked "Quit", but
a modal "Are you sure?" dialog is still waiting), or just the nested one
and not the main one (e.g. user clocked "Ok" in a modal dialog), or some
-other combination: In these cases, C will not work alone.
+other combination: In these cases, a simple C will not work.
The solution is to maintain "break this loop" variable for each C
invocation, and use a loop around C until the condition is
@@ -3890,12 +3990,12 @@
switching to a coroutine, you push the watcher onto the queue and notify
any waiters.
-To embed libev, see L, but in short, it's easiest to create two
+To embed libev, see L , but in short, it's easiest to create two
files, F and F that include the respective libev files:
// my_ev.h
#define EV_CB_DECLARE(type) struct my_coro *cb;
- #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb);
+ #define EV_CB_INVOKE(watcher) switch_to ((watcher)->cb)
#include "../libev/ev.h"
// my_ev.c
@@ -3951,14 +4051,14 @@
will work fine.
Proper exception specifications might have to be added to callbacks passed
-to libev: exceptions may be thrown only from watcher callbacks, all
-other callbacks (allocator, syserr, loop acquire/release and periodioc
-reschedule callbacks) must not throw exceptions, and might need a C specification. If you have code that needs to be compiled as both C
-and C++ you can use the C macro for this:
+to libev: exceptions may be thrown only from watcher callbacks, all other
+callbacks (allocator, syserr, loop acquire/release and periodic reschedule
+callbacks) must not throw exceptions, and might need a C
+specification. If you have code that needs to be compiled as both C and
+C++ you can use the C macro for this:
static void
- fatal_error (const char *msg) EV_THROW
+ fatal_error (const char *msg) EV_NOEXCEPT
{
perror (msg);
abort ();
@@ -3982,7 +4082,7 @@
the callback model to a model using method callbacks on objects.
To use it,
-
+
#include
This automatically includes F and puts all of its definitions (many
@@ -4095,7 +4195,7 @@
...
}
}
-
+
myfunctor f;
ev::io w;
@@ -4123,10 +4223,14 @@
=item w->set ([arguments])
-Basically the same as C, with the same arguments. Either this
-method or a suitable start method must be called at least once. Unlike the
-C counterpart, an active watcher gets automatically stopped and restarted
-when reconfiguring it with this method.
+Basically the same as C (except for C watchers>),
+with the same arguments. Either this method or a suitable start method
+must be called at least once. Unlike the C counterpart, an active watcher
+gets automatically stopped and restarted when reconfiguring it with this
+method.
+
+For C watchers this method is called C, to avoid
+clashing with the C method.
=item w->start ()
@@ -4240,6 +4344,14 @@
time of this writing, only C and C), to be found at
L.
+=item Javascript
+
+Node.js (L) uses libev as the underlying event library.
+
+=item Others
+
+There are others, and I stopped counting.
+
=back
@@ -4366,11 +4478,12 @@
ev_win32.c required on win32 platforms only
- ev_select.c only when select backend is enabled (which is enabled 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_port.c only when the solaris port backend is enabled (disabled by default)
+ ev_select.c only when select backend is enabled
+ ev_poll.c only when poll backend is enabled
+ ev_epoll.c only when the epoll backend is enabled
+ ev_linuxaio.c only when the linux aio backend is enabled
+ ev_kqueue.c only when the kqueue backend is enabled
+ ev_port.c only when the solaris port backend is enabled
F includes the backend files directly when enabled, so you only need
to compile this single file.
@@ -4548,6 +4661,13 @@
file descriptors again. Note that the replacement function has to close
the underlying OS handle.
+=item EV_USE_WSASOCKET
+
+If defined to be C<1>, libev will use C to create its internal
+communication socket, which works better in some environments. Otherwise,
+the normal C function will be used, which works better in other
+environments.
+
=item EV_USE_POLL
If defined to be C<1>, libev will compile in support for the C(2)
@@ -4562,6 +4682,13 @@
backend for GNU/Linux systems. If undefined, it will be enabled if the
headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
+=item EV_USE_LINUXAIO
+
+If defined to be C<1>, libev will compile in support for the Linux
+aio backend. Due to it's currenbt limitations it has to be requested
+explicitly. If undefined, it will be enabled on linux, otherwise
+disabled.
+
=item EV_USE_KQUEUE
If defined to be C<1>, libev will compile in support for the BSD style
@@ -4601,23 +4728,22 @@
=item EV_NO_THREADS
-If defined to be C<1>, libev will assume that it will never be called
-from different threads, which is a stronger assumption than C,
-above. This reduces dependencies and makes libev faster.
+If defined to be C<1>, libev will assume that it will never be called from
+different threads (that includes signal handlers), which is a stronger
+assumption than C, above. This reduces dependencies and makes
+libev faster.
=item EV_ATOMIC_T
Libev requires an integer type (suitable for storing C<0> or C<1>) whose
-access is atomic and serialised with respect to other threads or signal
-contexts. No such type is easily found in the C language, so you can
-provide your own type that you know is safe for your purposes. It is used
-both for signal handler "locking" as well as for signal and thread safety
-in C watchers.
+access is atomic with respect to other threads or signal contexts. No
+such type is easily found in the C language, so you can provide your own
+type that you know is safe for your purposes. It is used both for signal
+handler "locking" as well as for signal and thread safety in C
+watchers.
In the absence of this define, libev will use C
-(from F), which is usually good enough on most platforms,
-although strictly speaking using a type that also implies a memory fence
-is required.
+(from F), which is usually good enough on most platforms.
=item EV_H (h)
@@ -4995,7 +5121,7 @@
=back
-See also L.
+See also L .
=head3 COROUTINES
@@ -5274,6 +5400,11 @@
callback: The watcher callbacks have different type signatures, but libev
calls them using an C internally.
+=item null pointers and integer zero are represented by 0 bytes
+
+Libev uses C to initialise structs and arrays to C<0> bytes, and
+relies on this setting pointers and integers to null.
+
=item pointer accesses must be thread-atomic
Accessing a pointer value must be atomic, it must both be readable and
@@ -5296,8 +5427,8 @@
C could complicate things, however.
The most portable way to handle signals is to block signals in all threads
-except the initial one, and run the default loop in the initial thread as
-well.
+except the initial one, and run the signal handling loop in the initial
+thread as well.
=item C must be large enough for common memory allocation sizes
@@ -5411,7 +5542,7 @@
=item C backwards compatibility mechanism
The backward compatibility mechanism can be controlled by
-C. See L in the L
+C. See L"PREPROCESSOR SYMBOLS/MACROS"> in the L
section.
=item C and C have been removed
@@ -5464,7 +5595,7 @@
=item active
A watcher is active as long as it has been started and not yet stopped.
-See L for details.
+See L for details.
=item application
@@ -5510,7 +5641,7 @@
=item pending
A watcher is pending as soon as the corresponding event has been
-detected. See L for details.
+detected. See L for details.
=item real time