I've been reading the source code for node.js and v8 on my own.
When I tried to learn the architecture of Node.js in order to develop native modules, I ran into a similar issue as you.
What I'm writing here is my interpretation of node.js, which may or may not be correct.
Libev is the event loop that node.js uses internally to do simple event loop tasks. It was designed with *nix systems in mind. For the process to execute on, Libev provides a basic yet efficient event loop. More information on libev may be found here.
LibEio is a library for asynchronous input and output. It manages file descriptors, data handlers, and sockets, among other things. You may learn more about it by clicking here.
LibUv is a layer that sits on top of libeio, libev, c-ares (for DNS), and iocp (for windows asynchronous-io). All of the io and events in the event pool are performed, maintained, and managed by LibUv. (in libeio threadpool's example).
Basically, inside node.js, the v8 loop runs and handles all javascript and C++ modules [when they're running in a main thread (node.js is single threaded, according to the official documentation)]. libev and libeio manage it in the thread pool when it's not on the main thread, and libev handles the interaction with the main loop. So, as far as I can tell, node.js only has one persistent event loop: the v8 event loop. It uses a threadpool [through libeio & libev] to handle C++ async jobs.
For example:
eio_custom(Task,FLAG,AfterTask,Eio_REQUEST);
Calling the Task function in the threadpool is something that exists in all modules. When it's finished, it invokes the main thread's AfterTask method. The request handler, on the other hand, is a structure or object whose purpose is to provide communication between the threadpool and the main thread.
To know more about Node JS, It's recommended to join Node JS Certification Course today.