> On Apr 23, 2018, at 09:55, Jameson Nash <[email protected]> wrote: > > Instead of task switching deep inside some callback, could you run the libuv > event processing as a separate task, via `uv_run(uv_default_loop, > UV_RUN_ONCE)`, then task switch from outside the library? That would let > libuv finish updating all of its internal structures and remove itself from > the stack before anything else happens.
The short answer is that yes, that could probably be done. I thought about it before and concluded it would be a lot of work on gevent's side and it might be slow. But maybe it's worth it. In order to do something like that, gevent would have to implement a second callback queue on top of the libuv loop. For each prepare/check/io/timer/idle watcher that libuv ran, instead of it actually calling the callback the application needed, libuv would run a gevent callback that caused gevent to queue the real application callback on gevent's internal queue. Then when libuv returned control, gevent would have to start iterating over that internal queue and running the application callbacks. (Application callbacks can do anything, including arbitrary coroutine switches.) That's probably a viable approach, it just isn't the way gevent is structured now. Native event loop watchers have always run the corresponding application callback when they are triggered by the event loop. This avoids the overhead of having to maintain a second callback queue. That does, however, expose a difference between libev and libuv: libev *internally* queues all of its ready watchers and runs them in order at the end of its internal loop---this is how it implements priorities---whereas libuv runs each type of watchers before moving on to the next step of its internal loop. So in libev, if a timer callback starts a new 0 duration timer, it won't run until the next iteration of the loop, but in libuv that new 0 duration timer callback will be called immediately. When I first encountered the timer issue and realised that difference, I did consider the idea of a second queue in order to make libuv work more like libev. But I dismissed it because of the assumed overhead, and because of the assumed implementation complexity. I think I'll take another look at that option and try to get a better idea about the complexity and overhead. Thanks for reminding me! Jason -- You received this message because you are subscribed to the Google Groups "libuv" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/libuv. For more options, visit https://groups.google.com/d/optout.
