Difference between requests and handles?

333 views
Skip to first unread message

bodo....@enabre.com

unread,
May 7, 2013, 1:03:06 PM5/7/13
to li...@googlegroups.com
Hello,

could somebody explain me the big difference between handles and requests in libuv?

I already noticed that handles are quite general (e.g. tcp, streams) while requests are more specific (e.g. uv_fs_t - fs work request).
So requests are just async because they take time to execute while handles wait for some uninfluenced event??

However I still am very unsure about how they are related together and would be glad if somebody could explain me this.

Regards,
Bodo

Fedor Indutny

unread,
May 7, 2013, 1:18:51 PM5/7/13
to li...@googlegroups.com
Hi,

Handles are mostly passive and only activated either by external action or by your own action. Requests however always needs to be started and usually are executing callbacks upon completion.

Cheers,
Fedor.


--
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 libuv+un...@googlegroups.com.
To post to this group, send email to li...@googlegroups.com.
Visit this group at http://groups.google.com/group/libuv?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

bodo....@enabre.com

unread,
May 20, 2013, 2:45:18 AM5/20/13
to li...@googlegroups.com, fe...@indutny.com
How do they differ internally?

Are they both executed in the event loop/thread pool?

Bodo

bodo....@enabre.com

unread,
May 20, 2013, 4:03:30 AM5/20/13
to li...@googlegroups.com, fe...@indutny.com
Update:

I read through a FreeBSD kqueue document and think that I now have a better view on things in libuv:

There is a system event queue and a application event queue.

On the system event queue we can register handles (e.g. socket readable) whereas the application event queue may put a task (request) in the thread pool.
When the task finishes executing it may emit a signal through the application event queue and is usable again.

First of all: Is this mainly correct?

Second: As I understood the application itself has to check manuelly if there are active events waiting.
This happens for example through a for loop. Wouldn't this block the process again? How does libuv check for new events without getting blocked?

Bodo

Saúl Ibarra Corretgé

unread,
May 20, 2013, 5:24:18 AM5/20/13
to li...@googlegroups.com
On 5/20/13 10:03 AM, bodo....@enabre.com wrote:
> Update:
>
> I read through a FreeBSD kqueue document and think that I now have a
> better view on things in libuv:
>
> There is a system event queue and a application event queue.
>
> On the system event queue we can register handles (e.g. socket readable)
> whereas the application event queue may put a task (request) in the
> thread pool.

Not all requests run on the thread pool. Currently work requests (those
used with uv_queue_work) and filesystem requests (uv_fs_*) run on the
thread pool, other requests such as the ones used for uv_connect,
uv_write or uv_shutdown do not.

> When the task finishes executing it may emit a signal through the
> application event queue and is usable again.
>
> First of all: Is this mainly correct?
>

Not entirely. That is true for 'work' requests, that is, those which run
in the thread pool, but other requests are handled differently. Any
request type will end up reporting the result of the operation in a
callback called from the event loop thread.

> Second: As I understood the application itself has to check manuelly if
> there are active events waiting.
> This happens for example through a for loop. Wouldn't this block the
> process again? How does libuv check for new events without getting blocked?
>

libuv uses epoll, kqueue, etc to wait for events for the specified
amount of time. If you are using libuv a call to uv_run will block the
entire process, but the eventloop will process timers, and fire
callbacks just fine, you don't need to manually poll the event loop
yourself.

--
Sa�l Ibarra Corretg�
http://about.me/saghul | http://saghul.net

Bodo Kaiser

unread,
May 20, 2013, 6:02:27 AM5/20/13
to li...@googlegroups.com

Am 20.05.2013 um 11:24 schrieb Saúl Ibarra Corretgé <sag...@gmail.com>:

> On 5/20/13 10:03 AM, bodo....@enabre.com wrote:
>> Update:
>>
>> I read through a FreeBSD kqueue document and think that I now have a
>> better view on things in libuv:
>>
>> There is a system event queue and a application event queue.
>>
>> On the system event queue we can register handles (e.g. socket readable)
>> whereas the application event queue may put a task (request) in the
>> thread pool.
>
> Not all requests run on the thread pool. Currently work requests (those used with uv_queue_work) and filesystem requests (uv_fs_*) run on the thread pool, other requests such as the ones used for uv_connect, uv_write or uv_shutdown do not.

Do the other requests then just be executed sync?

>
>> When the task finishes executing it may emit a signal through the
>> application event queue and is usable again.
>>
>> First of all: Is this mainly correct?
>>
>
> Not entirely. That is true for 'work' requests, that is, those which run in the thread pool, but other requests are handled differently. Any request type will end up reporting the result of the operation in a callback called from the event loop thread.
>
>> Second: As I understood the application itself has to check manuelly if
>> there are active events waiting.
>> This happens for example through a for loop. Wouldn't this block the
>> process again? How does libuv check for new events without getting blocked?
>>
>
> libuv uses epoll, kqueue, etc to wait for events for the specified amount of time. If you are using libuv a call to uv_run will block the entire process, but the eventloop will process timers, and fire callbacks just fine, you don't need to manually poll the event loop yourself.

I currently can only speak for kqueue do not know how epoll, etc. work.
As I understood so far kqueue`s kevent() is used to set new events and to retrieve active events.
So you are required to call kevent() to check for new events.
As you now said this manual check for new events is done through timers (so flibuv checks in an interval for new events)?

Can you recommend articles for further reading to this topic?

Bodo

>
> --
> Saúl Ibarra Corretgé
> http://about.me/saghul | http://saghul.net
>
> --
> You received this message because you are subscribed to a topic in the Google Groups "libuv" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/libuv/Ah-SIVEyv2Q/unsubscribe?hl=en-US.
> To unsubscribe from this group and all its topics, send an email to libuv+un...@googlegroups.com.

Saúl Ibarra Corretgé

unread,
May 20, 2013, 7:18:08 AM5/20/13
to li...@googlegroups.com

>> Not all requests run on the thread pool. Currently work requests (those used with uv_queue_work) and filesystem requests (uv_fs_*) run on the thread pool, other requests such as the ones used for uv_connect, uv_write or uv_shutdown do not.
>
> Do the other requests then just be executed sync?
>

No. A request is basically the representation of an action that will
happen later. They all take a callback where the result will be reported.

When you want to write data to a uv_tcp_t handl, for example, you'd
create a request, attach the buffers and call uv_write. Then libuv will
take care of watching the fd for writability and call the blocking
write() (or writev) syscall with the buffers you supplied. Once the
write has been performed, your callback will be called and you can free
the memory you allocated for the buffers, the request and what have you.

>>
>> libuv uses epoll, kqueue, etc to wait for events for the specified amount of time. If you are using libuv a call to uv_run will block the entire process, but the eventloop will process timers, and fire callbacks just fine, you don't need to manually poll the event loop yourself.
>
> I currently can only speak for kqueue do not know how epoll, etc. work.
> As I understood so far kqueue`s kevent() is used to set new events and to retrieve active events.
> So you are required to call kevent() to check for new events.

Yes, but libuv takes care of that for you.

> As you now said this manual check for new events is done through timers (so flibuv checks in an interval for new events)?
>

It's a bit more involved. If there are timers only, then libuv will
block for as much as the closest timer, if there are idle handles it
will do a 0 timeout poll, but if there are tcp handles only, for
example, if will do an unlimited poll, until an event happens on any of
the fds.

> Can you recommend articles for further reading to this topic?
>

I'm not an expert myself :-) but on what topic do you want to further
read? libuv abstracts platform dependent stuff such as the poll backend
and offers a completion-style API instead of a readiness-style one, but
that's kind of a detail of how libuv is implemented.

bodo....@enabre.com

unread,
May 20, 2013, 7:41:45 AM5/20/13
to li...@googlegroups.com
Thank you a lot!

This really helped me. 
I think I will proceed with reading the source code step for step.

Best Regards,
Bodo
Sa�l Ibarra Corretg�
http://about.me/saghul | http://saghul.net
Reply all
Reply to author
Forward
0 new messages