Пример #1
0
static void uv__poll(uv_loop_t* loop, DWORD timeout) {
  BOOL success;
  uv_req_t* req;
  OVERLAPPED_ENTRY overlappeds[128];
  ULONG count;
  ULONG i;
  int repeat;
  uint64_t timeout_time;

  timeout_time = loop->time + timeout;

  for (repeat = 0; ; repeat++) {
    success = GetQueuedCompletionStatusEx(loop->iocp,
                                          overlappeds,
                                          ARRAY_SIZE(overlappeds),
                                          &count,
                                          timeout,
                                          FALSE);

    if (success) {
      for (i = 0; i < count; i++) {
        /* Package was dequeued, but see if it is not a empty package
         * meant only to wake us up.
         */
        if (overlappeds[i].lpOverlapped) {
          req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
          uv_insert_pending_req(loop, req);
        }
      }

      /* Some time might have passed waiting for I/O,
       * so update the loop time here.
       */
      uv_update_time(loop);
    } else if (GetLastError() != WAIT_TIMEOUT) {
      /* Serious error */
      uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
    } else if (timeout > 0) {
      /* GetQueuedCompletionStatus can occasionally return a little early.
       * Make sure that the desired timeout target time is reached.
       */
      uv_update_time(loop);
      if (timeout_time > loop->time) {
        timeout = (DWORD)(timeout_time - loop->time);
        /* The first call to GetQueuedCompletionStatus should return very
         * close to the target time and the second should reach it, but
         * this is not stated in the documentation. To make sure a busy
         * loop cannot happen, the timeout is increased exponentially
         * starting on the third round.
         */
        timeout += repeat ? (1 << (repeat - 1)) : 0;
        continue;
      }
    }
    break;
  }
}
Пример #2
0
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
  DWORD timeout;
  int r;
  int ran_pending;
  void (*poll)(uv_loop_t* loop, DWORD timeout);

  if (pGetQueuedCompletionStatusEx)
    poll = &uv_poll_ex;
  else
    poll = &uv_poll;

  r = uv__loop_alive(loop);
  if (!r)
    uv_update_time(loop);

  while (r != 0 && loop->stop_flag == 0) {
    uv_update_time(loop);
    uv_process_timers(loop);

    ran_pending = uv_process_reqs(loop);
    uv_idle_invoke(loop);
    uv_prepare_invoke(loop);

    timeout = 0;
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
      timeout = uv_backend_timeout(loop);

    (*poll)(loop, timeout);

    uv_check_invoke(loop);
    uv_process_endgames(loop);

    if (mode == UV_RUN_ONCE) {
      /* UV_RUN_ONCE implies forward progress: at least one callback must have
       * been invoked when it returns. uv__io_poll() can return without doing
       * I/O (meaning: no callbacks) when its timeout expires - which means we
       * have pending timers that satisfy the forward progress constraint.
       *
       * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
       * the check.
       */
      uv_process_timers(loop);
    }

    r = uv__loop_alive(loop);
    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
      break;
  }

  /* The if statement lets the compiler compile it to a conditional store.
   * Avoids dirtying a cache line.
   */
  if (loop->stop_flag != 0)
    loop->stop_flag = 0;

  return r;
}
Пример #3
0
static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) {
  DWORD bytes;
  ULONG_PTR key;
  OVERLAPPED* overlapped;
  uv_req_t* req;
  int repeat;
  uint64_t timeout_time;

  timeout_time = loop->time + timeout;

  for (repeat = 0; ; repeat++) {
    GetQueuedCompletionStatus(loop->iocp,
                              &bytes,
                              &key,
                              &overlapped,
                              timeout);

    if (overlapped) {
      /* Package was dequeued */
      req = uv_overlapped_to_req(overlapped);
      uv_insert_pending_req(loop, req);

      /* Some time might have passed waiting for I/O,
       * so update the loop time here.
       */
      uv_update_time(loop);
    } else if (GetLastError() != WAIT_TIMEOUT) {
      /* Serious error */
      uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
    } else if (timeout > 0) {
      /* GetQueuedCompletionStatus can occasionally return a little early.
       * Make sure that the desired timeout target time is reached.
       */
      uv_update_time(loop);
      if (timeout_time > loop->time) {
        timeout = (DWORD)(timeout_time - loop->time);
        /* The first call to GetQueuedCompletionStatus should return very
         * close to the target time and the second should reach it, but
         * this is not stated in the documentation. To make sure a busy
         * loop cannot happen, the timeout is increased exponentially
         * starting on the third round.
         */
        timeout += repeat ? (1 << (repeat - 1)) : 0;
        continue;
      }
    }
    break;
  }
}
Пример #4
0
static void show_stats(uv_handle_t *handle, int status) {
  int64_t diff;

#if PRINT_STATS
  LOGF("connections: %d, read: %.1f gbit/s, write: %.1f gbit/s\n",
       read_sockets,
       gbit(nrecv, STATS_INTERVAL),
       gbit(nsent, STATS_INTERVAL));
#endif

  /* Exit if the show is over */
  if (!--stats_left) {

    uv_update_time();
    diff = uv_now() - start_time;

    LOGF("pump_%d: %.1f gbit/s\n", read_sockets,
        gbit(nrecv_total, diff));

    exit(0);
  }

  /* Reset read and write counters */
  nrecv = 0;
  nsent = 0;
}
Пример #5
0
static void uv_loop_init(uv_loop_t* loop) {
  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL) {
    uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
  }

  loop->refs = 0;

  uv_update_time(loop);

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  RB_INIT(&loop->timers);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  loop->ares_active_sockets = 0;
  loop->ares_chan = NULL;

  loop->last_error = uv_ok_;
}
Пример #6
0
int uv_run_prework(uv_run_state* state) {
  BOOL block;
 
  uv_update_time(state->loop);
  uv_process_timers(state->loop);

  // Call idle callbacks if nothing to do.
  if (state->loop->pending_reqs_tail == NULL &&
      state->loop->endgame_handles == NULL) {
    uv_idle_invoke(state->loop);
  }

  uv_process_reqs(state->loop);
  uv_process_endgames(state->loop);

  if (!UV_LOOP_ALIVE(state->loop))
    return FALSE;

  uv_prepare_invoke(state->loop);

  block = (state->loop->idle_handles == NULL &&
           state->loop->pending_reqs_tail == NULL &&
           state->loop->endgame_handles == NULL &&
           UV_LOOP_ALIVE(state->loop));
  if (block)
    state->timeout = uv_get_poll_timeout(state->loop);
  else
    state->timeout = 0;

  state->count = 0;

  return TRUE;
}
Пример #7
0
static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
  BOOL success;
  uv_req_t* req;
  OVERLAPPED_ENTRY overlappeds[128];
  ULONG count;
  ULONG i;

  success = pGetQueuedCompletionStatusEx(loop->iocp,
                                         overlappeds,
                                         ARRAY_SIZE(overlappeds),
                                         &count,
                                         timeout,
                                         FALSE);

  if (success) {
    for (i = 0; i < count; i++) {
      /* Package was dequeued */
      req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
      uv_insert_pending_req(loop, req);
    }

    /* Some time might have passed waiting for I/O,
     * so update the loop time here.
     */
    uv_update_time(loop);
  } else if (GetLastError() != WAIT_TIMEOUT) {
    /* Serious error */
    uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
  } else if (timeout > 0) {
    /* GetQueuedCompletionStatus can occasionally return a little early.
     * Make sure that the desired timeout is reflected in the loop time.
     */
    uv__time_forward(loop, timeout);
  }
}
Пример #8
0
static void uv_poll(uv_loop_t* loop, DWORD timeout) {
  DWORD bytes;
  ULONG_PTR key;
  OVERLAPPED* overlapped;
  uv_req_t* req;

  GetQueuedCompletionStatus(loop->iocp,
                            &bytes,
                            &key,
                            &overlapped,
                            timeout);

  if (overlapped) {
    /* Package was dequeued */
    req = uv_overlapped_to_req(overlapped);
    uv_insert_pending_req(loop, req);

    /* Some time might have passed waiting for I/O,
     * so update the loop time here.
     */
    uv_update_time(loop);
  } else if (GetLastError() != WAIT_TIMEOUT) {
    /* Serious error */
    uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
  } else if (timeout > 0) {
    /* GetQueuedCompletionStatus can occasionally return a little early.
     * Make sure that the desired timeout is reflected in the loop time.
     */
    uv__time_forward(loop, timeout);
  }
}
Пример #9
0
static void uv_loop_init() {
  /* Create an I/O completion port */
  LOOP->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (LOOP->iocp == NULL) {
    uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
  }

  LOOP->refs = 0;

  uv_update_time();

  LOOP->pending_reqs_tail = NULL;

  LOOP->endgame_handles = NULL;

  RB_INIT(&LOOP->timers);

  LOOP->check_handles = NULL;
  LOOP->prepare_handles = NULL;
  LOOP->idle_handles = NULL;

  LOOP->next_prepare_handle = NULL;
  LOOP->next_check_handle = NULL;
  LOOP->next_idle_handle = NULL;

  LOOP->last_error = uv_ok_;

  LOOP->err_str = NULL;
}
Пример #10
0
static void show_stats(uv_timer_t* handle, int status) {
  int64_t diff;
  int i;

#if PRINT_STATS
  LOGF("connections: %d, write: %.1f gbit/s\n",
       write_sockets,
       gbit(nsent, STATS_INTERVAL));
#endif

  /* Exit if the show is over */
  if (!--stats_left) {

    uv_update_time();
    diff = uv_now() - start_time;

    LOGF("%s_pump%d_client: %.1f gbit/s\n", type == TCP ? "tcp" : "pipe", write_sockets,
        gbit(nsent_total, diff));

    for (i = 0; i < write_sockets; i++) {
      uv_close(type == TCP ? (uv_handle_t*)&tcp_write_handles[i] : (uv_handle_t*)&pipe_write_handles[i], NULL);
    }

    exit(0);
  }

  /* Reset read and write counters */
  nrecv = 0;
  nsent = 0;
}
Пример #11
0
/*
 * Class:     com_oracle_libuv_handles_TimerHandle
 * Method:    _now
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_com_oracle_libuv_handles_TimerHandle__1now
  (JNIEnv *env, jclass cls, jlong loop) {

  assert(loop);
  uv_loop_t* lp = reinterpret_cast<uv_loop_t*>(loop);
  uv_update_time(lp);
  return uv_now(lp);
}
Пример #12
0
static void read_show_stats() {
  int64_t diff;

  uv_update_time();
  diff = uv_now() - start_time;

  LOGF("%s_pump%d_server: %.1f gbit/s\n", type == TCP ? "tcp" : "pipe", max_read_sockets,
      gbit(nrecv_total, diff));
}
Пример #13
0
static int uv__run(uv_loop_t* loop) {
  uv_update_time(loop);
  uv__run_timers(loop);
  uv__run_idle(loop);
  uv__run_prepare(loop);
  uv__poll(loop);
  uv__run_check(loop);
  uv__run_closing_handles(loop);
  return uv__has_active_handles(loop) || uv__has_active_reqs(loop);
}
Пример #14
0
static int LuaIO_process_uptime(lua_State* L) {
  uint64_t uptime;
  uv_loop_t* loop = uv_default_loop();

  uv_update_time(loop);
  uptime = uv_now(loop) - LuaIO_get_start_time();
  lua_pushinteger(L, uptime);

  return 1;
}
static void once_cb(uv_timer_t* handle) {
  TUV_ASSERT(handle != NULL);
  TUV_ASSERT(0 == uv_is_active((uv_handle_t*) handle));

  once_cb_called++;

  uv_close((uv_handle_t*)handle, once_close_cb);

  /* Just call this randomly for the code coverage. */
  uv_update_time(uv_default_loop());
}
Пример #16
0
static bool
uv_loop_source_check(void *data)
{
    uv_loop_t *loop = data;

    uv_update_time(loop);

    bool returnValue = uv_loop_alive(loop);
    SOL_DBG("Returning %s", returnValue ? "true" : "false");
    return returnValue;
}
Пример #17
0
int uv_loop_init(uv_loop_t* loop) {
  /* Initialize libuv itself first */
  uv__once_init();

  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL)
    return uv_translate_sys_error(GetLastError());

  /* To prevent uninitialized memory access, loop->time must be initialized
   * to zero before calling uv_update_time for the first time.
   */
  loop->time = 0;
  uv_update_time(loop);

  QUEUE_INIT(&loop->wq);
  QUEUE_INIT(&loop->handle_queue);
  QUEUE_INIT(&loop->active_reqs);
  loop->active_handles = 0;

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  RB_INIT(&loop->timers);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);

  loop->active_tcp_streams = 0;
  loop->active_udp_streams = 0;

  loop->timer_counter = 0;
  loop->stop_flag = 0;

  if (uv_mutex_init(&loop->wq_mutex))
    abort();

  if (uv_async_init(loop, &loop->wq_async, uv__work_done))
    abort();

  uv__handle_unref(&loop->wq_async);
  loop->wq_async.flags |= UV__HANDLE_INTERNAL;

  return 0;
}
Пример #18
0
static void once_cb(uv_timer_t* handle, int status) {
  printf("ONCE_CB %d\n", once_cb_called);

  ASSERT(handle != NULL);
  ASSERT(status == 0);

  once_cb_called++;

  uv_close((uv_handle_t*)handle, once_close_cb);

  /* Just call this randomly for the code coverage. */
  uv_update_time(uv_default_loop());
}
Пример #19
0
static void start_stats_collection() {
  int r;

  /* Show-stats timer */
  stats_left = STATS_COUNT;
  r = uv_timer_init(loop, &timer_handle);
  ASSERT(r == 0);
  r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL);
  ASSERT(r == 0);

  uv_update_time(loop);
  start_time = uv_now(loop);
}
Пример #20
0
static void start_stats_collection() {
  uv_req_t* req = req_alloc();
  int r;

  /* Show-stats timer */
  stats_left = STATS_COUNT;
  r = uv_timer_init(&timer_handle);
  ASSERT(r == 0);
  r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL);
  ASSERT(r == 0);

  uv_update_time();
  start_time = uv_now();
}
Пример #21
0
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
  int r;
  void (*poll)(uv_loop_t* loop, int block);

  if (pGetQueuedCompletionStatusEx)
    poll = &uv_poll_ex;
  else
    poll = &uv_poll;

  if (!uv__loop_alive(loop))
    return 0;

  r = uv__loop_alive(loop);
  while (r != 0 && loop->stop_flag == 0) {
    uv_update_time(loop);
    uv_process_timers(loop);

    /* Call idle callbacks if nothing to do. */
    if (loop->pending_reqs_tail == NULL &&
        loop->endgame_handles == NULL) {
      uv_idle_invoke(loop);
    }

    uv_process_reqs(loop);
    uv_process_endgames(loop);

    uv_prepare_invoke(loop);

    (*poll)(loop, loop->idle_handles == NULL &&
                  loop->pending_reqs_tail == NULL &&
                  loop->endgame_handles == NULL &&
                  !loop->stop_flag &&
                  (loop->active_handles > 0 ||
                   !ngx_queue_empty(&loop->active_reqs)) &&
                  !(mode & UV_RUN_NOWAIT));

    uv_check_invoke(loop);
    r = uv__loop_alive(loop);
    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
      break;
  }

  /* The if statement lets the compiler compile it to a conditional store.
   * Avoids dirtying a cache line.
   */
  if (loop->stop_flag != 0)
    loop->stop_flag = 0;

  return r;
}
Пример #22
0
static int _do_fork_fs_events_child(int file_or_dir) {
  /* basic fsevents work in the child after a fork */
  pid_t child_pid;
  uv_loop_t loop;

  /* Watch in the parent, prime the loop and/or threads. */
  assert_watch_file_current_dir(uv_default_loop(), file_or_dir);
  child_pid = fork();
  ASSERT(child_pid != -1);

  if (child_pid != 0) {
    /* parent */
    assert_wait_child(child_pid);
  } else {
    /* child */
    /* Ee can watch in a new loop, but dirs only work
       if we're on linux. */
#if defined(__APPLE__)
    file_or_dir = FS_TEST_FILE;
#endif
    printf("Running child\n");
    uv_loop_init(&loop);
    printf("Child first watch\n");
    assert_watch_file_current_dir(&loop, file_or_dir);
    ASSERT(0 == uv_loop_close(&loop));
    printf("Child second watch default loop\n");
    /* Ee can watch in the default loop. */
    ASSERT(0 == uv_loop_fork(uv_default_loop()));
    /* On some platforms (OS X), if we don't update the time now,
     * the timer cb fires before the event loop enters uv__io_poll,
     * instead of after, meaning we don't see the change! This may be
     * a general race.
     */
    uv_update_time(uv_default_loop());
    assert_watch_file_current_dir(uv_default_loop(), file_or_dir);

    /* We can close the parent loop successfully too. This is
       especially important on Apple platforms where if we're not
       careful trying to touch the CFRunLoop, even just to shut it
       down, that we allocated in the FS_TEST_DIR case would crash. */
    ASSERT(0 == uv_loop_close(uv_default_loop()));

    printf("Exiting child \n");
  }

  MAKE_VALGRIND_HAPPY();
  return 0;

}
Пример #23
0
static void read_cb(uv_stream_t* stream, ssize_t bytes, uv_buf_t buf) {
  if (nrecv_total == 0) {
    ASSERT(start_time == 0);
    uv_update_time();
    start_time = uv_now();
  }

  if (bytes < 0) {
    uv_close((uv_handle_t*)stream, read_sockets_close_cb);
    return;
  }

  buf_free(buf);

  nrecv += bytes;
  nrecv_total += bytes;
}
Пример #24
0
static void uv_loop_init(uv_loop_t* loop) {
  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL) {
    uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
  }

  uv_update_time(loop);

#ifndef UV_LEAN_AND_MEAN
  ngx_queue_init(&loop->active_handles);
  ngx_queue_init(&loop->active_reqs);
#else
  loop->active_handles = 0;
  loop->active_reqs = 0;
#endif

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  RB_INIT(&loop->timers);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);

  loop->channel = NULL;
  RB_INIT(&loop->ares_handles);

  loop->active_tcp_streams = 0;
  loop->active_udp_streams = 0;

  loop->last_err = uv_ok_;

  memset(&loop->counters, 0, sizeof loop->counters);
}
Пример #25
0
static void uv_loop_init(uv_loop_t* loop) {
  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL) {
    uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
  }

  /* To prevent uninitialized memory access, loop->time must be intialized */
  /* to zero before calling uv_update_time for the first time. */
  loop->time = 0;
  uv_update_time(loop);

  ngx_queue_init(&loop->handle_queue);
  ngx_queue_init(&loop->active_reqs);
  loop->active_handles = 0;

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  RB_INIT(&loop->timers);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);

  loop->channel = NULL;
  RB_INIT(&loop->ares_handles);

  loop->active_tcp_streams = 0;
  loop->active_udp_streams = 0;

  loop->last_err = uv_ok_;

  memset(&loop->counters, 0, sizeof loop->counters);
}
Пример #26
0
static int pound_it(int concurrency,
                    const char* type,
                    setup_fn do_setup,
                    connect_fn do_connect,
                    make_connect_fn make_connect,
                    void* arg) {
  double secs;
  int r;
  uint64_t start_time; /* in ns */
  uint64_t end_time;

  loop = uv_default_loop();

  uv_update_time(loop);
  start = uv_now(loop);

  /* Run benchmark for at least five seconds. */
  start_time = uv_hrtime();

  do_setup(concurrency, arg);

  r = do_connect(concurrency, make_connect, arg);
  ASSERT(!r);

  uv_run(loop, UV_RUN_DEFAULT);

  end_time = uv_hrtime();

  /* Number of fractional seconds it took to run the benchmark. */
  secs = (double)(end_time - start_time) / NANOSEC;

  fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
          type,
          concurrency,
          closed_streams / secs,
          conns_failed);
  fflush(stderr);

  MAKE_VALGRIND_HAPPY();
  return 0;
}
Пример #27
0
int uv_loop_init(uv_loop_t* loop) {
  struct heap* timer_heap;
  int err;

  /* Initialize libuv itself first */
  uv__once_init();

  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL)
    return uv_translate_sys_error(GetLastError());

  /* To prevent uninitialized memory access, loop->time must be initialized
   * to zero before calling uv_update_time for the first time.
   */
  loop->time = 0;
  uv_update_time(loop);

  QUEUE_INIT(&loop->wq);
  QUEUE_INIT(&loop->handle_queue);
  loop->active_reqs.count = 0;
  loop->active_handles = 0;

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
  if (timer_heap == NULL) {
    err = UV_ENOMEM;
    goto fail_timers_alloc;
  }

  heap_init(timer_heap);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);

  loop->active_tcp_streams = 0;
  loop->active_udp_streams = 0;

  loop->timer_counter = 0;
  loop->stop_flag = 0;

  err = uv_mutex_init(&loop->wq_mutex);
  if (err)
    goto fail_mutex_init;

  err = uv_async_init(loop, &loop->wq_async, uv__work_done);
  if (err)
    goto fail_async_init;

  uv__handle_unref(&loop->wq_async);
  loop->wq_async.flags |= UV_HANDLE_INTERNAL;

  err = uv__loops_add(loop);
  if (err)
    goto fail_async_init;

  return 0;

fail_async_init:
  uv_mutex_destroy(&loop->wq_mutex);

fail_mutex_init:
  uv__free(timer_heap);
  loop->timer_heap = NULL;

fail_timers_alloc:
  CloseHandle(loop->iocp);
  loop->iocp = INVALID_HANDLE_VALUE;

  return err;
}
Пример #28
0
 ///!
 ///  ...
 ///  Internally, this function just calls uv_update_time() function.
 ///
 void
 update_time()
 {
     uv_update_time(uv_loop_);
 }
Пример #29
0
int luv_update_time(lua_State* L) {
  uv_update_time(uv_default_loop());
  return 0;
}
Пример #30
0
int uv_run_jx(uv_loop_t* loop, uv_run_mode mode, void (*triggerSync)(const int),
              const int tid) {
  int r;
  void (*poll)(uv_loop_t * loop, int block);

  if (pGetQueuedCompletionStatusEx)
    poll = &uv_poll_ex;
  else
    poll = &uv_poll;

  if (tid != THREAD_ID_ALREADY_DEFINED) {
    if (tid != THREAD_ID_NOT_DEFINED)
      loop->loopId = tid;
    else
      loop->loopId = 63;
  }

  if (!uv__loop_alive(loop)) return 0;

  r = uv__loop_alive(loop);
  while (r != 0 && loop->stop_flag == 0) {
    uv_update_time(loop);
    uv_process_timers(loop);

    /* Call idle callbacks if nothing to do. */
    if (loop->pending_reqs_tail == NULL && loop->endgame_handles == NULL) {
      uv_idle_invoke(loop);
    }

    uv_process_reqs(loop);
    uv_process_endgames(loop);
    uv_prepare_invoke(loop);

    if (loop->loopId >= 0 && mode == UV_RUN_DEFAULT) {
      if (threadMessages[loop->loopId] != 0 && triggerSync != NULL) {
        triggerSync(loop->loopId);
      }
    }

    if (mode != UV_RUN_PAUSE) {
      (*poll)(loop, loop->idle_handles == NULL && threadMessages[loop->loopId] == 0 &&
                        loop->pending_reqs_tail == NULL &&
                        loop->endgame_handles == NULL && !loop->stop_flag &&
                        (loop->active_handles > loop->fakeHandle ||
                         !QUEUE_EMPTY(&loop->active_reqs)) &&
                        !(mode & UV_RUN_NOWAIT));
    }

    uv_check_invoke(loop);
    r = uv__loop_alive(loop);
    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT | UV_RUN_PAUSE)) break;
  }

  if (loop->loopId >= 0 && mode == UV_RUN_DEFAULT && triggerSync != NULL) {
    triggerSync(loop->loopId);
  }

  // if we force thread shutdown, there will be some remaining tasks etc.
  // It is highly possible they might leak, below impl. tries to workaround
  // this problem by looping the handles for 500 ms. at max.
  // TODO(obastemur) make it configurable per thread / timer sensitive
  if (loop->stop_flag != 0) {
    loop->stop_flag = 0;
    if (mode != UV_RUN_DEFAULT || r == 0) return r;

    int force_close = uv__loop_alive(loop);
    if (force_close) {
      uint64_t start_time = uv_hrtime();

      int ret_val = 1;
      while (ret_val) {
        ret_val = uv_run_jx(loop, UV_RUN_NOWAIT,
                             triggerSync, THREAD_ID_ALREADY_DEFINED);
        uint64_t end_time = uv_hrtime();
        if(end_time - start_time > 500 * 1024 * 1024) {
          break;
        }
      }
	}
  }

  return r;
}