Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Libev: how to schedule a callback to be called as soon as possible

Tags:

c

timeout

libev

I'm learning libev and I've stumbled upon this question. Assume that I want to process something as soon as possible but not now (i.e. not in the current executing function). For example I want to divide some big synchronous job into multiple pieces that will be queued so that other callbacks can fire in between. In other words I want to schedule a callback with timeout 0.

So the first idea is to use ev_timer with timeout 0. The first question is: is that efficient? Is libev capable of transforming 0 timeout timer into an efficient "call as soon as possible" job? I assume it is not.

I've been digging through libev's docs and I found other options as well:

it can artificially delay invoking the callback by using a prepare or idle watcher

So the idle watcher is probably not going to be good here because

Idle watchers trigger events when no other events of the same or higher priority are pending

Which probably is not what I want. Prepare watchers might work here. But why not check watcher? Is there any crutial difference in the context I'm talking about?

The other option these docs suggest is:

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);

But that would require to always have a stopped watcher. Also since I don't know a priori how many calls I want to schedule at the same time then I would have to have multiple watchers and additionally keep track of them via some kind of list and increase it when needed.

So am I on the right track? Are these all possibilities or am I missing something simple?

like image 639
freakish Avatar asked Oct 30 '22 10:10

freakish


1 Answers

You may want to check out the ev_prepare watcher. That one is scheduled for execution as the last handler in the given event loop iteration. It can be used for 'Execute this task ASAP' implementations. You can create dedicated watcher for each task you want to execute, or you can implement a queue with a one prepare watcher that is started once queue contains at least one task.

Alternatively, you can implement similar mechanism using ev_idle watcher, but this time, it will be executed only if the application doesn't process any 'higher priority' watcher handlers.

like image 119
Ales Teska Avatar answered Nov 15 '22 08:11

Ales Teska