10 ms·
An introduction to libuv (2016)
- ridiculous_fish 8y agolibuv supports child processes via fork, such as in uv_spawn. It also uses multiple threads to support uv_fs_stat, etc. How does it handle the well known incompatibility between fork and threads?
- oconnor663 8y agoWhich incompatibility do you mean? If you're forking to create a child process, usually you're just careful not to do anything that might acquire a lock (including allocating memory) in between the fork and the exec, and then I think you're good? Forking for something else, though, god help you.
- ridiculous_fish 8y agoThe tricky part of this approach is error handling. What if a system call fails in between fork and exec, or exec itself? It looks like libuv creates a pipe for every new process, and uses that to send errno back on any failing system call. This has the disadvantage that you only get the error code, and none of the context. You get ENOENT, but you don't know which path was invalid.
- geofft 8y agoThey could just write the entire error string to an fd, right? It's annoying in C to write a formatted string without doing dynamic allocations, but it's possible. (Or, if you want to be weird, do a PTRACE_TRACEME after fork and have the parent trace the child process and only detach when it sees a successful return from execve. If ptrace is unavailable, fall back to less-useful errors)
- ridiculous_fish 8y agoPiping back the error string is probably the best one can do.
- noselasd 8y agoDo you need to know ? If you're fork/exec and get ENOENT, there's only one path that could relate to, the path to the program you wanted to run.
- majewsky 8y agoOr the path to the interpreter (e.g. if you're trying to run a x86-32 binary on an x86-64 system without 32-bit libc, or if you're trying to run a binary linked against glibc on a system with musl).
- noselasd 8y agoFair enough - but there's still no more info you could learn from the ENOENT error.
- tapirl 8y ago> This book and the code is based on libuv version v1.3.0. libuv v1.30 was release at on Jan 28, 2015. It is at v1.22.0.
- nsm 8y agoOriginal author here. Yes this book was written a long time ago when I was into the node ecosystem. A lot of the book was copied into the official docs later https://github.com/libuv/libuv/pull/1246 https://github.com/libuv/libuv/pull/1246. The book definitely does not capture new things. I do not intend to update it, but I still look at pull requests.
- saghul 8y agoI merged it into the official docs, thanks a lot for all your work nsm! <3
- newnewpdro 8y agoWhy is the hello world example [0] unnecessarily allocating and freeing the uv_loop_t? When I see this kind of crap right out of the gate I immediately begin suspecting this is probably a pile of awful code written by a novice C programmer then documented and published as if it's the best thing since sliced bread. Much of the value in making a struct (and hence its size) public and supplying a pointer to the initializer is the potential to embed or avoid heap allocation of the thing altogether, and here in an example which would benefit from both the simplified code in addition to demonstrating the advantage, it's completely missed. Fixed form: int main() { uv_loop_t loop; uv_loop_init(&loop); printf("Now quitting.\n"); uv_run(&loop, UV_RUN_DEFAULT); uv_loop_close(&loop); return 0; } [0] https://nikhilm.github.io/uvbook/basics.html#hello-world https://nikhilm.github.io/uvbook/basics.html#hello-world
- CJefferson 8y agoGenerally, you only create one uv_loop_t, and it is vital it is never copied (which is easy to do accisentally if you stack allocate it). mallocing is the entirely sensible thing to do here.
- newnewpdro 8y agoThen uv_loop_t should be an opaque type so its size isn't known at all, and uv_loop_init() should instead be uv_loop_new() returning the heap-allocated uv_loop_t, and uv_loop_close() renamed to uv_loop_free(). As-is the API and the way its use is being demonstrated in that example appear amateur to say the least.
- viraptor 8y agoBut then you wouldn't be able to stack allocate it. It's reasonable to make something recommended, but not forbid other approaches if someone really wants to do it that way. You don't have to go to either extreme.
- TomMarius 8y agoI wouldn't call a library that is the foundation of one of the most popular platforms in the world amateur.
- nosefrog 8y agoI work with Nikhil. He's incredibly smart and a fantastic programmer. Didn't know he wrote a book on libuv though!
- saghul 8y agoWe merged this guide into http://docs.libuv.org/en/v1.x/guide.html http://docs.libuv.org/en/v1.x/guide.html which got some updates to match API changes.
- Keyframe 8y agoIs libuv used anywhere else outside of node?
- snarfy 8y agoI'm pretty sure aspnetcore uses it.
- sasmithjr 8y agoThe default for Kestrel has been moved off of libuv, but you can choose to use libuv if you'd like. https://blogs.msdn.microsoft.com/webdev/2018/04/12/asp-net-core-2-1-0-preview2-improvements-to-the-kestrel-http-server/ https://blogs.msdn.microsoft.com/webdev/2018/04/12/asp-net-c...
- gajjanag 8y agoThe Julia programming language uses it.
- piquadrat 8y agoThere's an event loop implementation for Python based on libuv: https://github.com/MagicStack/uvloop https://github.com/MagicStack/uvloop It's compatible with the native asyncio event loop and can be used as a drop-in replacement.
- insertnickname 8y agohttps://github.com/libuv/libuv/wiki/Projects-that-use-libuv https://github.com/libuv/libuv/wiki/Projects-that-use-libuv
- bmease 8y agoneovim uses libuv.
- djs55 8y agoThere's a very good OCaml binding: https://github.com/fdopen/uwt https://github.com/fdopen/uwt . It works really well in the networking component of the Docker for Mac and Windows desktop apps (see https://github.com/moby/vpnkit https://github.com/moby/vpnkit)