Using EV_CUSTOM for custom events

Zsbán Ambrus ambrus at
Fri Apr 27 22:03:46 CEST 2012

On 4/27/12, Konstantin Osipov <kostja at> wrote:
> Could you please confirm that I understood your explanation
> correctly:
> When event loop is not blocked (sleeping) ev_async_send() does not
> have to write to a pipe, even if executed from a different thread.
> In that case, what does it use, some sort of atomic?

Yes, it usually doesn't have to write to a pipe.  Obviously it may
have to still write to a pipe if the event loop is just about to
sleep, otherwise there'd be a race.

Here's how I understand this is implemented, but read the source if
you really want to know what's done exactly.  The full power of
atomics are never needed for this, only memory fences are.  The event
loop has a flag to tell when it's safe not to write to the pipe.
Before the event loop would sleep, it clears that flag, does a memory
fence, then checks for the last time whether there are pending asyncs.
 When the event loop wakes up, it sets the flag.  The ev_async_send
call first marks the async as pending, then does a memory fence, then
checks that flag of the loop, and writes to the pipe to wake up the
loop only if that flag is clear.  If the flag is set, then the event
loop will surely notice the pending async watcher even before the next
time it would go to sleep.

> OK, a timer with zero timeout looks safer than a watcher on a
> signal, since in the latter case there could be spurious wake-ups.

There wouldn't be, because you never actually _start_ the signal
watcher, so it never watches for anything.  You just make it pending
with the ev_feed_event function, which makes the loop run its callback
next time.  What kind of watcher it is doesn't really matter if the
watcher is not active.

Note that if you make a watcher pending this way, then the event loop
will reference it, so you can't free its memory until you call
ev_signal_stop which clears its pending state.


More information about the libev mailing list