I think it is quite correct. But there are some nuances, actually
writes and reads are non-blocking. Libuv will queue everything until
the OS will tell it that data could be read/written. So the most
*blocking* thing here is a user callbacks, and that means that
everything is up to you! ;)

On Wed, Jan 22, 2014 at 9:06 PM,  <[email protected]> wrote:
> Ok, after reading more on of the source code, watching the Google Tech
> Talk on Node.js and considering your answers, this is a rough attemp to
> make sense of what happens in libuv when you have, for instance, a HTTP
> request asking for a file (assume Node.js using libuv):
>
> 1) The default event loop listening to TCP connections will run the
> callback for accepting the connection.
>
> 2) The connection is accepted, and the OS notifies that there's data to
> be read in the socket.
>
> [default loop dealing with other requests...]
>
> 3) The request (data) will be read in the main thread up to a certain
> limit to avoid starvation (32 iterations, as in `uv__read`).
>
> 4) The user callback will be called inside this libuv callback, still
> in the main thread. It will parse the request, and upon finding that it
> should read a file, will call the FS abstraction asking for that file.
> If we assume Node.js here, this callback means a V8 invocation running
> in the main thread, and no other requests can be served in the mean
> time.
>
> 5) The call to read a file will spawn asynchronous work by calling
> `uv__work_submit`. The task will be performed in another thread, and
> `uv_sync_asend` will send the file contents through a socket (pipe?)
> when it's done.
>
> [async request running and default loop dealing with other requests...]
>
> 6) The file contents will be received by a watcher in the main thread,
> and the default event loop will read it all and call the user callback
> with the file contents. No requests can be served while we're doing
> that.
>
> 7) The user callback (still running in the main thread) will write the
> response to the client. No requests can be served while we're doing
> that.
>
>
> I think I may have mistaken some parts, especially in step 4 and in the
> parts where requests can't be served in steps 6 and 7. I'm assuming a
> small request and a small file.
>
> Is this more or less correct or did I get it all wrong?
>
>
> Thank you for the patience :)
> Allan
>
> On Wednesday, January 22, 2014 9:18:06 AM UTC-2, Fedor Indutny wrote:
>>
>> I mean using the same TCP server fd in multiple threads each with it's
>> own libuv loop. You'll still need to send the `uv_tcp_t` server handle
>> to other threads using IPC pipe (see `uv_pipe_open`).
>>
>> On Wed, Jan 22, 2014 at 3:14 PM,  <[email protected]> wrote:
>> > What do you mean by listening on the same fd?
>> >
>> > I have used the other approach when using libevent (one event loop
>> > giving
>> > control of the fds to other event loops in other threads).
>> >
>> > On Wednesday, January 22, 2014 9:11:29 AM UTC-2, Fedor Indutny wrote:
>> >>
>> >> Hello again!
>> >>
>> >> Sorry for not answering all of your questions.
>> >>
>> >> libuv is a single-threaded library, and everything, except,
>> >> uv_work_cb's are executed in the same thread, where uv_run() "runs".
>> >> There are at least two ways, how you could make libuv-based app use
>> >> all available CPUs: load-balancing incoming sockets via IPC pipes to
>> >> child process or worker threads (each with it's own libuv loop) or
>> >> listening on the same fd.
>> >>
>> >> Node.js was using latter approach up until v0.11 that will become v0.12
>> >> soon.
>> >>
>> >> Cheers,
>> >> Fedor.
>> >>
>> >> On Wed, Jan 22, 2014 at 3:02 PM,  <[email protected]> wrote:
>> >> > Thank you for the answers! I used libevent previously, so I was
>> >> > confused about the different nature of libuv.
>> >> >
>> >> > I took a look at the NodeJS source code, and how it uses libuv, and
>> >> > one
>> >> > question remains.
>> >> >
>> >> > Is the default event loop/main thread used for everything? Assuming a
>> >> > request comes in, this thread alone will: get notified about the
>> >> > event,
>> >> > read the data, run the callback, and then write back a response? All
>> >> > of
>> >> > this on a single thread, for any number of requests?
>> >> >
>> >> > I read parts of the NodeJS code, but I couldn't find anything that
>> >> > points to any thread parallelism (except from debugging). It seems
>> >> > that
>> >> > even uv_queue_work is not even being called much.
>> >> >
>> >> >
>> >> > If this question is too specific, let me know and I'll ask it in the
>> >> > NodeJS mailing list.
>> >> >
>> >> >
>> >> > Allan
>> >> >
>> >> > On Friday, January 17, 2014 4:35:40 PM UTC-2, Fedor Indutny wrote:
>> >> >>
>> >> >> Hello!
>> >> >>
>> >> >> You should not call anything except `uv_async_send()` from another
>> >> >> thread. Many functions are inserting stuff into loop's linked lists
>> >> >> and the list itself is not thread-safe (not even talking about many
>> >> >> other internals).
>> >> >>
>> >> >> `uv_async_send()` indeed writes to one end of the pipe, and libuv is
>> >> >> listening on the other end of the pipe, and interrupts loop and
>> >> >> invokes callback when receives data.
>> >> >>
>> >> >> As a way to return data back from uv_work_cb - you could set and
>> >> >> change req.data safely inside worker thread, it'll be available in
>> >> >> uv_work_done_cb.
>> >> >>
>> >> >> Cheers,
>> >> >> Fedor.
>> >> >>
>> >> >> On Fri, Jan 17, 2014 at 6:19 PM,  <[email protected]> wrote:
>> >> >> > Hi,
>> >> >> >
>> >> >> > I've been curious about how libuv works internally regarding
>> >> >> > thread
>> >> >> > communication.
>> >> >> >
>> >> >> > This is what I understand:
>> >> >> > There's a single thread running uv_run. If I spawn some work to be
>> >> >> > done
>> >> >> > in another thread I'm supposed to use uv_queue_work. The way to
>> >> >> > send
>> >> >> > the results of this work back to the main thread is through
>> >> >> > uv_async_send (which is the only thread-safe function in libuv).
>> >> >> >
>> >> >> > This is what I want to do:
>> >> >> > Start listening on a TCP socket, accept incoming connections in
>> >> >> > the
>> >> >> > default loop, and wait for data to be available for reading (using
>> >> >> > uv_read_start). When it's available for reading, I'd put the work
>> >> >> > (socket reading) in the queue (with uv_queue_work), and the
>> >> >> > callback
>> >> >> > for this would run in another thread, reading the data and
>> >> >> > performing
>> >> >> > some work based on it, which may involve writing data back to this
>> >> >> > or
>> >> >> > any other socket.
>> >> >> >
>> >> >> > So, my questions related to this are:
>> >> >> > - Is this possible to do? If I call uv_read_start and uv_write in
>> >> >> > another thread, can this cause trouble, because they should have
>> >> >> > been
>> >> >> > called in the default loop?
>> >> >> >
>> >> >> > - If uv_read_start and uv_write should be called in the default
>> >> >> > loop,
>> >> >> > then the main thread will be responsible for reading and writing
>> >> >> > all
>> >> >> > data, right? Wouldn't this impact performance? How does NodeJS
>> >> >> > deal
>> >> >> > with this?
>> >> >> >
>> >> >> > - How does uv_async_send work? From a quick glance at the source
>> >> >> > code,
>> >> >> > I suspect it sends data in a file descriptor, which will be read
>> >> >> > in
>> >> >> > the
>> >> >> > default loop. Is this what is happening?
>> >> >> >
>> >> >> >
>> >> >> > Allan
>> >> >> >
>> >> >> > --
>> >> >> > 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 http://groups.google.com/group/libuv.
>> >> >> > For more options, visit https://groups.google.com/groups/opt_out.

-- 
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 http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to