Skip to content
Alexander Belopolsky edited this page Sep 30, 2017 · 14 revisions

Async Notes

Libuv sample code

The source distribution of libuv comes with a test test-embed.c demonstrating how to embed a libuv event loop in another loop.

Overview

The sample app has the following components:

  1. An external loop;
  2. An embed_timer scheduled on the default loop;
  3. The embed thread; and
  4. The embed_async task.

The program sets up its components and then enters the external loop:

  uv_run(&external, UV_RUN_DEFAULT);

At the same time, the embed thread obtains the backend fd of the default loop

    fd = uv_backend_fd(uv_default_loop());

and goes to sleep waiting for events to appear on fd:

    r = epoll_wait(fd, &ev, 1, timeout);

Once an event is received, the embed thread wakes up the external loop by making an async call to embed_async and waits for embed_cb to raise the embed_sem semaphore.

    uv_async_send(&embed_async);
    uv_sem_wait(&embed_sem);

Before raising the semaphore, the embed_async task processes events on the default loop:

static void embed_cb(uv_async_t* async) {
  uv_run(uv_default_loop(), UV_RUN_ONCE);
  uv_sem_post(&embed_sem);
}

How is a event generated got the backend_fd?

Let's run the embed test code with a breakpoint in kevent. The first break occurs in both threads:

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 13.1
    frame #0: 0x00007fff94d9dd8c libsystem_kernel.dylib`kevent
libsystem_kernel.dylib`kevent:
->  0x7fff94d9dd8c <+0>:  movl   $0x200016b, %eax          ; imm = 0x200016B
    0x7fff94d9dd91 <+5>:  movq   %rcx, %r10
    0x7fff94d9dd94 <+8>:  syscall
    0x7fff94d9dd96 <+10>: jae    0x7fff94d9dda0            ; <+20>
  thread #2, stop reason = breakpoint 13.1
    frame #0: 0x00007fff94d9dd8c libsystem_kernel.dylib`kevent
libsystem_kernel.dylib`kevent:
->  0x7fff94d9dd8c <+0>:  movl   $0x200016b, %eax          ; imm = 0x200016B
    0x7fff94d9dd91 <+5>:  movq   %rcx, %r10
    0x7fff94d9dd94 <+8>:  syscall
    0x7fff94d9dd96 <+10>: jae    0x7fff94d9dda0            ; <+20>
Target 0: (run-tests) stopped.

Clone this wiki locally