Skip to content
Search

Libuv:Design

lastmod 2018-08-17created 2016-01-169 edits

libuv is a cross-platform library written for Node.js. It is designed around an event-driven asynchronous I/O model. It provides a simple abstraction on top of various I/O polling mechanisms.

Handles and requests

libuv is provided as a combination of an event loop and two abstraction objects.

  • Handle
  • Request

The I/O loop

libuv Loop iteration The I/O Loop (or Event loop) is the central part of libuv. It sets up the context for all I/O operations and is meant to be tied to a single thread.

Warning

Multiple event loops each run in a different thread, and the event loop is not thread-safe unless stated otherwise. 1

The event loop uses the usual single-threaded asynchronous I/O approach. Polling of all (network) I/O non-blocking sockets uses the best mechanism available on the given platform.

  • epoll on Linux
  • kqueue on OSX and other BSDs
  • event ports on SunOS
  • IOCP on Windows.

The loop proceeds in the following order.

  1. An update takes place. The current time is cached to reduce the number of system calls.
  2. If the LOOP is not alive, it exits immediately. The LOOP is alive if a reference handle is active, a request is active, or a handle is closing (closing handle). 2
  3. Due timers are run.
  4. Pending callbacks are called. All I/O callbacks are called after I/O polling. If deferral to the next loop is needed, it runs at this point. If the previous iteration was deferred, all I/O callbacks are called at this point.
  5. Idle handle callbacks are called.
  6. Prepare handle callbacks are called.
  7. The poll timeout is calculated. The rules for calculating the timeout are as follows:
    • If the loop was run with the UV_RUN_NOWAIT flag, the timeout is 0.
    • If the loop is going to be stopped (uv_stop() was called), the timeout is 0.
    • If there are no active handles or requests, the timeout is 0.
    • If there are any idle handles active, the timeout is 0.
    • If there are any handles pending to be closed, the timeout is 0.
    • If none of the above cases was matched, the timeout of the closest timer is taken, or if there are no active timers, infinity.
  8. The loop blocks for I/O.
  9. Check handle callbacks are called.
  10. Close callbacks are called.
  11. Special case in case the loop was run with UV_RUN_ONCE, as it implies forward progress.
  12. Iteration ends.

Important

libuv uses a thread pool to make asynchronous file I/O operations possible, but network I/O always runs on a single thread.

Favorite site

References


  1. Original: The libuv event loop is not thread-safe except where stated otherwise ↩

  2. Original: If a loop has active and ref'd handles, active requests or closing handles it's considered to be alive. ↩