ev_set_priority
, despite the name, does not in itself do what you want, it only changes the relative order of callback invocation, with one exception: ev_idle
watchers.
For ev_idle
watchers, the lower priority watchers are indeed not invoked when other events, or higher priority idle watchers, are pending. For example, ev_idle watchers with priority 0 will be handled when there are no other pending watchers with priority 0 (the default), i.e. it will only be invoked when no other events with priority 0 are pending. Libev will check for more events before making this decision, so for as long as there are events with priority 0 or higher, it will not invoke idle watchers with priority 0 or lower.
One way to solve your problem is to only start an ev_idle
watcher in the io callback for your non-preferred socket with a priority equal to the priority on the io watcher, causing it to not be handled until all other events are handled.
A slight variation would be to mark your low prioprity io watchers in some sort of set and start a single ev_idle watcher, which then goes through all sockets in your set.
Another, completely different way would be to look into embeddable event loops and move all lower priority io watchers into an embedded loop. In your ev_embed
watcher callback you can then start an idle watcher to later call ev_embed_sweep
. This has the advantage of needing fewer idle watchers and moving all the processing for the low-priority sockets into their own event loop, so they don't cause extra latency issues for your high priority io watcher.