edit: it appears that I'm confused as to what this does exactly, my bad. Egg, all over my face.
edit: it appears that I'm confused as to what this does exactly, my bad. Egg, all over my face.
So if Go has this feature, using libuv would not only be useless, it would be harmful because it doesn't play nice with the language runtime w.r.t. parallelism.
I think that writing asynchronous parallel code should be done by the compiler and the runtime, not by the coder. Node.js code is a mess of callbacks that have to be written in continuation passing style by the user. Haskell (or Go?) code that has the same effect is written like regular imperative code, which is transformed into Node-style callback code by the compiler and multiplexed by the runtime. Compilers are excellent in doing this kind of transformations.
From http://golang.org/doc/effective_go.html#goroutines: "Goroutines are multiplexed onto multiple OS threads so if one should block, such as while waiting for I/O, others continue to run."
So the Go runtime doesn't automagically transform blocking system calls into non-blocking calls, but if one goroutine is waiting for I/O, other goroutines can run in the meantime.
But you're right in that with Go you can write simple, easy to debug imperative code, but at the same time confidently spawn 10's of thousands of goroutines because they're so lightweight compared to conventional OS threads. The Go runtime handles the bookkeeping of multiplexing goroutines over real OS threads.
But when using Go's standard file.read or socket.write, what you get is I/O multiplexing of goroutines (with epoll or kqueue) in the runtime.
Naturally, if you call a C library from Go that uses unix read or write and executes a blocking system call, that cannot be magically intercepted by the Go runtime.
It makes me wonder, what happens to a goroutine when a system call blocks. Go is supposed to mux many goroutines to a smaller number of OS threads, but what happens when one of those threads has been blocked in a system call?
There are plenty of vague descriptions on how goroutines work but none of the ones I found quickly explained what happens on a blocking system call that allows another goroutine to run, apart from hand-waving about "another goroutine running".
See pkg/runtime/proc.c (entersyscall, ready, and matchmg).