|
|
|
@ -508,7 +508,9 @@ events to filter out spurious ones, recreating the set when required. Last
|
|
|
|
|
not least, it also refuses to work with some file descriptors which work
|
|
|
|
|
perfectly fine with C<select> (files, many character devices...).
|
|
|
|
|
|
|
|
|
|
Epoll is truly the train wreck analog among event poll mechanisms.
|
|
|
|
|
Epoll is truly the train wreck analog among event poll mechanisms,
|
|
|
|
|
a frankenpoll, cobbled together in a hurry, no thought to design or
|
|
|
|
|
interaction with others.
|
|
|
|
|
|
|
|
|
|
While stopping, setting and starting an I/O watcher in the same iteration
|
|
|
|
|
will result in some caching, there is still a system call per such
|
|
|
|
@ -1616,26 +1618,19 @@ fd as you want (as long as you don't confuse yourself). Setting all file
|
|
|
|
|
descriptors to non-blocking mode is also usually a good idea (but not
|
|
|
|
|
required if you know what you are doing).
|
|
|
|
|
|
|
|
|
|
If you cannot use non-blocking mode, then force the use of a
|
|
|
|
|
known-to-be-good backend (at the time of this writing, this includes only
|
|
|
|
|
C<EVBACKEND_SELECT> and C<EVBACKEND_POLL>). The same applies to file
|
|
|
|
|
descriptors for which non-blocking operation makes no sense (such as
|
|
|
|
|
files) - libev doesn't guarantee any specific behaviour in that case.
|
|
|
|
|
|
|
|
|
|
Another thing you have to watch out for is that it is quite easy to
|
|
|
|
|
receive "spurious" readiness notifications, that is your callback might
|
|
|
|
|
receive "spurious" readiness notifications, that is, your callback might
|
|
|
|
|
be called with C<EV_READ> but a subsequent C<read>(2) will actually block
|
|
|
|
|
because there is no data. Not only are some backends known to create a
|
|
|
|
|
lot of those (for example Solaris ports), it is very easy to get into
|
|
|
|
|
this situation even with a relatively standard program structure. Thus
|
|
|
|
|
it is best to always use non-blocking I/O: An extra C<read>(2) returning
|
|
|
|
|
C<EAGAIN> is far preferable to a program hanging until some data arrives.
|
|
|
|
|
because there is no data. It is very easy to get into this situation even
|
|
|
|
|
with a relatively standard program structure. Thus it is best to always
|
|
|
|
|
use non-blocking I/O: An extra C<read>(2) returning C<EAGAIN> is far
|
|
|
|
|
preferable to a program hanging until some data arrives.
|
|
|
|
|
|
|
|
|
|
If you cannot run the fd in non-blocking mode (for example you should
|
|
|
|
|
not play around with an Xlib connection), then you have to separately
|
|
|
|
|
re-test whether a file descriptor is really ready with a known-to-be good
|
|
|
|
|
interface such as poll (fortunately in our Xlib example, Xlib already
|
|
|
|
|
does this on its own, so its quite safe to use). Some people additionally
|
|
|
|
|
interface such as poll (fortunately in the case of Xlib, it already does
|
|
|
|
|
this on its own, so its quite safe to use). Some people additionally
|
|
|
|
|
use C<SIGALRM> and an interval timer, just to be sure you won't block
|
|
|
|
|
indefinitely.
|
|
|
|
|
|
|
|
|
@ -1673,16 +1668,48 @@ There is no workaround possible except not registering events
|
|
|
|
|
for potentially C<dup ()>'ed file descriptors, or to resort to
|
|
|
|
|
C<EVBACKEND_SELECT> or C<EVBACKEND_POLL>.
|
|
|
|
|
|
|
|
|
|
=head3 The special problem of files
|
|
|
|
|
|
|
|
|
|
Many people try to use C<select> (or libev) on file descriptors
|
|
|
|
|
representing files, and expect it to become ready when their program
|
|
|
|
|
doesn't block on disk accesses (which can take a long time on their own).
|
|
|
|
|
|
|
|
|
|
However, this cannot ever work in the "expected" way - you get a readiness
|
|
|
|
|
notification as soon as the kernel knows whether and how much data is
|
|
|
|
|
there, and in the case of open files, that's always the case, so you
|
|
|
|
|
always get a readiness notification instantly, and your read (or possibly
|
|
|
|
|
write) will still block on the disk I/O.
|
|
|
|
|
|
|
|
|
|
Another way to view it is that in the case of sockets, pipes, character
|
|
|
|
|
devices and so on, there is another party (the sender) that delivers data
|
|
|
|
|
on it's own, but in the case of files, there is no such thing: the disk
|
|
|
|
|
will not send data on it's own, simply because it doesn't know what you
|
|
|
|
|
wish to read - you would first have to request some data.
|
|
|
|
|
|
|
|
|
|
Since files are typically not-so-well supported by advanced notification
|
|
|
|
|
mechanism, libev tries hard to emulate POSIX behaviour with respect
|
|
|
|
|
to files, even though you should not use it. The reason for this is
|
|
|
|
|
convenience: sometimes you want to watch STDIN or STDOUT, which is
|
|
|
|
|
usually a tty, often a pipe, but also sometimes files or special devices
|
|
|
|
|
(for example, C<epoll> on Linux works with F</dev/random> but not with
|
|
|
|
|
F</dev/urandom>), and even though the file might better be served with
|
|
|
|
|
asynchronous I/O instead of with non-blocking I/O, it is still useful when
|
|
|
|
|
it "just works" instead of freezing.
|
|
|
|
|
|
|
|
|
|
So avoid file descriptors pointing to files when you know it (e.g. use
|
|
|
|
|
libeio), but use them when it is convenient, e.g. for STDIN/STDOUT, or
|
|
|
|
|
when you rarely read from a file instead of from a socket, and want to
|
|
|
|
|
reuse the same code path.
|
|
|
|
|
|
|
|
|
|
=head3 The special problem of fork
|
|
|
|
|
|
|
|
|
|
Some backends (epoll, kqueue) do not support C<fork ()> at all or exhibit
|
|
|
|
|
useless behaviour. Libev fully supports fork, but needs to be told about
|
|
|
|
|
it in the child.
|
|
|
|
|
it in the child if you want to continue to use it in the child.
|
|
|
|
|
|
|
|
|
|
To support fork in your programs, you either have to call
|
|
|
|
|
C<ev_default_fork ()> or C<ev_loop_fork ()> after a fork in the child,
|
|
|
|
|
enable C<EVFLAG_FORKCHECK>, or resort to C<EVBACKEND_SELECT> or
|
|
|
|
|
C<EVBACKEND_POLL>.
|
|
|
|
|
To support fork in your child processes, you have to call C<ev_loop_fork
|
|
|
|
|
()> after a fork in the child, enable C<EVFLAG_FORKCHECK>, or resort to
|
|
|
|
|
C<EVBACKEND_SELECT> or C<EVBACKEND_POLL>.
|
|
|
|
|
|
|
|
|
|
=head3 The special problem of SIGPIPE
|
|
|
|
|
|
|
|
|
@ -3472,6 +3499,144 @@ To exit from any of these loops, just set the corresponding exit variable:
|
|
|
|
|
// exit both
|
|
|
|
|
exit_main_loop = exit_nested_loop = 1;
|
|
|
|
|
|
|
|
|
|
=item Thread locking example
|
|
|
|
|
|
|
|
|
|
Here is a fictitious example of how to run an event loop in a different
|
|
|
|
|
thread than where callbacks are being invoked and watchers are
|
|
|
|
|
created/added/removed.
|
|
|
|
|
|
|
|
|
|
For a real-world example, see the C<EV::Loop::Async> perl module,
|
|
|
|
|
which uses exactly this technique (which is suited for many high-level
|
|
|
|
|
languages).
|
|
|
|
|
|
|
|
|
|
The example uses a pthread mutex to protect the loop data, a condition
|
|
|
|
|
variable to wait for callback invocations, an async watcher to notify the
|
|
|
|
|
event loop thread and an unspecified mechanism to wake up the main thread.
|
|
|
|
|
|
|
|
|
|
First, you need to associate some data with the event loop:
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
mutex_t lock; /* global loop lock */
|
|
|
|
|
ev_async async_w;
|
|
|
|
|
thread_t tid;
|
|
|
|
|
cond_t invoke_cv;
|
|
|
|
|
} userdata;
|
|
|
|
|
|
|
|
|
|
void prepare_loop (EV_P)
|
|
|
|
|
{
|
|
|
|
|
// for simplicity, we use a static userdata struct.
|
|
|
|
|
static userdata u;
|
|
|
|
|
|
|
|
|
|
ev_async_init (&u->async_w, async_cb);
|
|
|
|
|
ev_async_start (EV_A_ &u->async_w);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init (&u->lock, 0);
|
|
|
|
|
pthread_cond_init (&u->invoke_cv, 0);
|
|
|
|
|
|
|
|
|
|
// now associate this with the loop
|
|
|
|
|
ev_set_userdata (EV_A_ u);
|
|
|
|
|
ev_set_invoke_pending_cb (EV_A_ l_invoke);
|
|
|
|
|
ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
|
|
|
|
|
|
|
|
|
|
// then create the thread running ev_loop
|
|
|
|
|
pthread_create (&u->tid, 0, l_run, EV_A);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The callback for the C<ev_async> watcher does nothing: the watcher is used
|
|
|
|
|
solely to wake up the event loop so it takes notice of any new watchers
|
|
|
|
|
that might have been added:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
async_cb (EV_P_ ev_async *w, int revents)
|
|
|
|
|
{
|
|
|
|
|
// just used for the side effects
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The C<l_release> and C<l_acquire> callbacks simply unlock/lock the mutex
|
|
|
|
|
protecting the loop data, respectively.
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_release (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_acquire (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The event loop thread first acquires the mutex, and then jumps straight
|
|
|
|
|
into C<ev_run>:
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
l_run (void *thr_arg)
|
|
|
|
|
{
|
|
|
|
|
struct ev_loop *loop = (struct ev_loop *)thr_arg;
|
|
|
|
|
|
|
|
|
|
l_acquire (EV_A);
|
|
|
|
|
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
|
|
|
|
ev_run (EV_A_ 0);
|
|
|
|
|
l_release (EV_A);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Instead of invoking all pending watchers, the C<l_invoke> callback will
|
|
|
|
|
signal the main thread via some unspecified mechanism (signals? pipe
|
|
|
|
|
writes? C<Async::Interrupt>?) and then waits until all pending watchers
|
|
|
|
|
have been called (in a while loop because a) spurious wakeups are possible
|
|
|
|
|
and b) skipping inter-thread-communication when there are no pending
|
|
|
|
|
watchers is very beneficial):
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_invoke (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
while (ev_pending_count (EV_A))
|
|
|
|
|
{
|
|
|
|
|
wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
|
|
|
|
|
pthread_cond_wait (&u->invoke_cv, &u->lock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Now, whenever the main thread gets told to invoke pending watchers, it
|
|
|
|
|
will grab the lock, call C<ev_invoke_pending> and then signal the loop
|
|
|
|
|
thread to continue:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
real_invoke_pending (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
ev_invoke_pending (EV_A);
|
|
|
|
|
pthread_cond_signal (&u->invoke_cv);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Whenever you want to start/stop a watcher or do other modifications to an
|
|
|
|
|
event loop, you will now have to lock:
|
|
|
|
|
|
|
|
|
|
ev_timer timeout_watcher;
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
ev_timer_start (EV_A_ &timeout_watcher);
|
|
|
|
|
ev_async_send (EV_A_ &u->async_w);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
|
|
|
|
|
Note that sending the C<ev_async> watcher is required because otherwise
|
|
|
|
|
an event loop currently blocking in the kernel will have no knowledge
|
|
|
|
|
about the newly added timer. By waking up the loop it will pick up any new
|
|
|
|
|
watchers in the next event loop iteration.
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4473,143 +4638,7 @@ watcher callback into the event loop interested in the signal.
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
=head4 THREAD LOCKING EXAMPLE
|
|
|
|
|
|
|
|
|
|
Here is a fictitious example of how to run an event loop in a different
|
|
|
|
|
thread than where callbacks are being invoked and watchers are
|
|
|
|
|
created/added/removed.
|
|
|
|
|
|
|
|
|
|
For a real-world example, see the C<EV::Loop::Async> perl module,
|
|
|
|
|
which uses exactly this technique (which is suited for many high-level
|
|
|
|
|
languages).
|
|
|
|
|
|
|
|
|
|
The example uses a pthread mutex to protect the loop data, a condition
|
|
|
|
|
variable to wait for callback invocations, an async watcher to notify the
|
|
|
|
|
event loop thread and an unspecified mechanism to wake up the main thread.
|
|
|
|
|
|
|
|
|
|
First, you need to associate some data with the event loop:
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
mutex_t lock; /* global loop lock */
|
|
|
|
|
ev_async async_w;
|
|
|
|
|
thread_t tid;
|
|
|
|
|
cond_t invoke_cv;
|
|
|
|
|
} userdata;
|
|
|
|
|
|
|
|
|
|
void prepare_loop (EV_P)
|
|
|
|
|
{
|
|
|
|
|
// for simplicity, we use a static userdata struct.
|
|
|
|
|
static userdata u;
|
|
|
|
|
|
|
|
|
|
ev_async_init (&u->async_w, async_cb);
|
|
|
|
|
ev_async_start (EV_A_ &u->async_w);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init (&u->lock, 0);
|
|
|
|
|
pthread_cond_init (&u->invoke_cv, 0);
|
|
|
|
|
|
|
|
|
|
// now associate this with the loop
|
|
|
|
|
ev_set_userdata (EV_A_ u);
|
|
|
|
|
ev_set_invoke_pending_cb (EV_A_ l_invoke);
|
|
|
|
|
ev_set_loop_release_cb (EV_A_ l_release, l_acquire);
|
|
|
|
|
|
|
|
|
|
// then create the thread running ev_loop
|
|
|
|
|
pthread_create (&u->tid, 0, l_run, EV_A);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The callback for the C<ev_async> watcher does nothing: the watcher is used
|
|
|
|
|
solely to wake up the event loop so it takes notice of any new watchers
|
|
|
|
|
that might have been added:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
async_cb (EV_P_ ev_async *w, int revents)
|
|
|
|
|
{
|
|
|
|
|
// just used for the side effects
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The C<l_release> and C<l_acquire> callbacks simply unlock/lock the mutex
|
|
|
|
|
protecting the loop data, respectively.
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_release (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_acquire (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
The event loop thread first acquires the mutex, and then jumps straight
|
|
|
|
|
into C<ev_run>:
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
l_run (void *thr_arg)
|
|
|
|
|
{
|
|
|
|
|
struct ev_loop *loop = (struct ev_loop *)thr_arg;
|
|
|
|
|
|
|
|
|
|
l_acquire (EV_A);
|
|
|
|
|
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
|
|
|
|
ev_run (EV_A_ 0);
|
|
|
|
|
l_release (EV_A);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Instead of invoking all pending watchers, the C<l_invoke> callback will
|
|
|
|
|
signal the main thread via some unspecified mechanism (signals? pipe
|
|
|
|
|
writes? C<Async::Interrupt>?) and then waits until all pending watchers
|
|
|
|
|
have been called (in a while loop because a) spurious wakeups are possible
|
|
|
|
|
and b) skipping inter-thread-communication when there are no pending
|
|
|
|
|
watchers is very beneficial):
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
l_invoke (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
while (ev_pending_count (EV_A))
|
|
|
|
|
{
|
|
|
|
|
wake_up_other_thread_in_some_magic_or_not_so_magic_way ();
|
|
|
|
|
pthread_cond_wait (&u->invoke_cv, &u->lock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Now, whenever the main thread gets told to invoke pending watchers, it
|
|
|
|
|
will grab the lock, call C<ev_invoke_pending> and then signal the loop
|
|
|
|
|
thread to continue:
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
real_invoke_pending (EV_P)
|
|
|
|
|
{
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
ev_invoke_pending (EV_A);
|
|
|
|
|
pthread_cond_signal (&u->invoke_cv);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Whenever you want to start/stop a watcher or do other modifications to an
|
|
|
|
|
event loop, you will now have to lock:
|
|
|
|
|
|
|
|
|
|
ev_timer timeout_watcher;
|
|
|
|
|
userdata *u = ev_userdata (EV_A);
|
|
|
|
|
|
|
|
|
|
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock (&u->lock);
|
|
|
|
|
ev_timer_start (EV_A_ &timeout_watcher);
|
|
|
|
|
ev_async_send (EV_A_ &u->async_w);
|
|
|
|
|
pthread_mutex_unlock (&u->lock);
|
|
|
|
|
|
|
|
|
|
Note that sending the C<ev_async> watcher is required because otherwise
|
|
|
|
|
an event loop currently blocking in the kernel will have no knowledge
|
|
|
|
|
about the newly added timer. By waking up the loop it will pick up any new
|
|
|
|
|
watchers in the next event loop iteration.
|
|
|
|
|
See also L<Thread locking example>.
|
|
|
|
|
|
|
|
|
|
=head3 COROUTINES
|
|
|
|
|
|
|
|
|
|