// File: nilnilnil[P]autocomplete/deps/mongoose/mongoose.c
// Function: master_thread
static void master_thread(struct mg_context *ctx) {
  fd_set read_set;
  struct timeval tv;
  struct socket *sp;
  int max_fd;

  while (ctx->stop_flag == 0) {
    FD_ZERO(&read_set);
    max_fd = -1;

    // Add listening sockets to the read set
    for (sp = ctx->listening_sockets; sp != NULL; sp = sp->next) {
      add_to_set(sp->sock, &read_set, &max_fd);
    }

    tv.tv_sec = 0;
    tv.tv_usec = 200 * 1000;

    if (select(max_fd + 1, &read_set, NULL, NULL, &tv) < 0) {
#ifdef _WIN32
      // On windows, if read_set and write_set are empty,
      // select() returns "Invalid parameter" error
      // (at least on my Windows XP Pro). So in this case, we sleep here.
      sleep(1);
#endif // _WIN32
    } else {
      for (sp = ctx->listening_sockets; sp != NULL; sp = sp->next) {
        if (FD_ISSET(sp->sock, &read_set)) {
          accept_new_connection(sp, ctx);
        }
      }
    }
  }
  DEBUG_TRACE(("stopping workers"));

  // Stop signal received: somebody called mg_stop. Quit.
  close_all_listening_sockets(ctx);

  // Wakeup workers that are waiting for connections to handle.
  pthread_cond_broadcast(&ctx->sq_full);

  // Wait until all threads finish
  (void) pthread_mutex_lock(&ctx->mutex);
  while (ctx->num_threads > 0) {
    (void) pthread_cond_wait(&ctx->cond, &ctx->mutex);
  }
  (void) pthread_mutex_unlock(&ctx->mutex);

  // All threads exited, no sync is needed. Destroy mutex and condvars
  (void) pthread_mutex_destroy(&ctx->mutex);
  (void) pthread_cond_destroy(&ctx->cond);
  (void) pthread_cond_destroy(&ctx->sq_empty);
  (void) pthread_cond_destroy(&ctx->sq_full);

  // Signal mg_stop() that we're done
  ctx->stop_flag = 2;

  DEBUG_TRACE(("exiting"));
}

// Assembly:
subq $0xb8, %rsp
movq %rdi, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
movl (%rax), %eax
cmpl $0x0, %eax
jne 0x1924e
jmp 0x19104
leaq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
movl 0x10(%rsp), %eax
cmpq $0x10, %rax
jae 0x1913e
movq 0x8(%rsp), %rax
movl 0x10(%rsp), %ecx
movq $0x0, (%rax,%rcx,8)
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x19116
jmp 0x19140
movl $0xffffffff, 0x14(%rsp) # imm = 0xFFFFFFFF
movq 0xb0(%rsp), %rax
movq 0xd0(%rax), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
je 0x1918a
movq 0x18(%rsp), %rax
movl 0x8(%rax), %edi
leaq 0x30(%rsp), %rsi
leaq 0x14(%rsp), %rdx
callq 0x1b170
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x1915c
movq $0x0, 0x20(%rsp)
movq $0x30d40, 0x28(%rsp)    # imm = 0x30D40
movl 0x14(%rsp), %edi
addl $0x1, %edi
leaq 0x30(%rsp), %rsi
xorl %eax, %eax
movl %eax, %ecx
leaq 0x20(%rsp), %r8
movq %rcx, %rdx
callq 0x5520
cmpl $0x0, %eax
jge 0x191c3
jmp 0x19249
movq 0xb0(%rsp), %rax
movq 0xd0(%rax), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
je 0x19247
movq 0x18(%rsp), %rax
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq 0x30(%rsp,%rax,8), %rax
movq %rax, (%rsp)
movq 0x18(%rsp), %rax
movl 0x8(%rax), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq (%rsp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x19236
movq 0x18(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x1b1f0
jmp 0x19238
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
jmp 0x191d7
jmp 0x19249
jmp 0x190ef
movq 0xb0(%rsp), %rdi
callq 0x1ae40
movq 0xb0(%rsp), %rdi
addq $0x640, %rdi            # imm = 0x640
callq 0x51b0
movq 0xb0(%rsp), %rdi
addq $0xe0, %rdi
callq 0x58a0
movq 0xb0(%rsp), %rax
movl 0xd8(%rax), %eax
cmpl $0x0, %eax
jle 0x192bb
movq 0xb0(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq 0xb0(%rsp), %rsi
addq $0xe0, %rsi
callq 0x5910
jmp 0x19283
movq 0xb0(%rsp), %rdi
addq $0xe0, %rdi
callq 0x53e0
movq 0xb0(%rsp), %rdi
addq $0xe0, %rdi
callq 0x5690
movq 0xb0(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x5b40
movq 0xb0(%rsp), %rdi
addq $0x670, %rdi            # imm = 0x670
callq 0x5b40
movq 0xb0(%rsp), %rdi
addq $0x640, %rdi            # imm = 0x640
callq 0x5b40
movq 0xb0(%rsp), %rax
movl $0x2, (%rax)
addq $0xb8, %rsp
retq
nopw %cs:(%rax,%rax)