From 5cf190b99b58aa331248add4a0ac5d7b6cec5ecb Mon Sep 17 00:00:00 2001
From: root ev_child
- wait for pid status changesev_idle
- when you've got nothing better to doev_prepare
and ev_check
- customise your event loopev_embed
- when one backend isn't enough
Returns the set of backends that are embeddable in other event loops. This
+is the theoretical, all-platform, value. To find which backends
+might be supported on the current system, you would need to look at
+ev_embeddable_backends () & ev_supported_backends ()
, likewise for
+recommended ones.
See the description of ev_embed
watchers for more info.
Sets the allocation function to use (the prototype is similar to the
@@ -933,6 +943,10 @@ of the SIGxxx
constants).
ev_child
- wait for pid status changesPrepare and check watchers are usually (but not always) used in tandem: prepare watchers get invoked before the process blocks and check watchers afterwards.
-Their main purpose is to integrate other event mechanisms into libev. This -could be used, for example, to track variable changes, implement your own -watchers, integrate net-snmp or a coroutine library and lots more.
+Their main purpose is to integrate other event mechanisms into libev and +their use is somewhat advanced. This could be used, for example, to track +variable changes, implement your own watchers, integrate net-snmp or a +coroutine library and lots more.
This is done by examining in each prepare call which file descriptors need
to be watched by the other library, registering ev_io
watchers for
them and starting an ev_timer
watcher for any timeouts (many libraries
@@ -1049,6 +1064,72 @@ macros, but using them is utterly, utterly and completely pointless.
ev_embed
- when one backend isn't enoughThis is a rather advanced watcher type that lets you embed one event loop +into another.
+There are primarily two reasons you would want that: work around bugs and +prioritise I/O.
+As an example for a bug workaround, the kqueue backend might only support +sockets on some platform, so it is unusable as generic backend, but you +still want to make use of it because you have many sockets and it scales +so nicely. In this case, you would create a kqueue-based loop and embed it +into your default loop (which might use e.g. poll). Overall operation will +be a bit slower because first libev has to poll and then call kevent, but +at least you can use both at what they are best.
+As for prioritising I/O: rarely you have the case where some fds have +to be watched and handled very quickly (with low latency), and even +priorities and idle watchers might have too much overhead. In this case +you would put all the high priority stuff in one loop and all the rest in +a second one, and embed the second one in the first.
+As long as the watcher is started it will automatically handle events. The
+callback will be invoked whenever some events have been handled. You can
+set the callback to 0
to avoid having to specify one if you are not
+interested in that.
Also, there have not currently been made special provisions for forking:
+when you fork, you not only have to call ev_loop_fork
on both loops,
+but you will also have to stop and restart any ev_embed
watchers
+yourself.
Unfortunately, not all backends are embeddable, only the ones returned by
+ev_embeddable_backends
are, which, unfortunately, does not include any
+portable one.
So when you want to use this feature you will always have to be prepared +that you cannot get an embeddable loop. The recommended way to get around +this is to have a separate variables for your embeddable loop, try to +create it, and if that fails, use the normal loop for everything:
+struct ev_loop *loop_hi = ev_default_init (0); + struct ev_loop *loop_lo = 0; + struct 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 () + ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ()) + : 0; + + // if we got one, then embed it, otherwise default to loop_hi + if (loop_lo) + { + ev_embed_init (&embed, 0, loop_lo); + ev_embed_start (loop_hi, &embed); + } + else + loop_lo = loop_hi; + ++
Configures the watcher to embed the given loop, which must be embeddable.
+