Beispiel #1
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;
}
Beispiel #2
0
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
  int timeout;
  int r;

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

  while (r != 0 && loop->stop_flag == 0) {
    UV_TICK_START(loop, mode);

    uv__update_time(loop);
    uv__run_timers(loop);
    uv__run_pending(loop);
    uv__run_idle(loop);
    uv__run_prepare(loop);

    timeout = 0;
    if ((mode & UV_RUN_NOWAIT) == 0)
      timeout = uv_backend_timeout(loop);

    uv__io_poll(loop, timeout);
    uv__run_check(loop);
    uv__run_closing_handles(loop);

    if (mode == UV_RUN_ONCE) {
      /* UV_RUN_ONCE implies forward progess: 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__update_time(loop);
      uv__run_timers(loop);
    }

    r = uv__loop_alive(loop);
    UV_TICK_STOP(loop, mode);

    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
      break;
  }

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

  return r;
}
Beispiel #3
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;
}
Beispiel #4
0
int uv_run2(uv_loop_t* loop, uv_run_mode mode) {
  int r;

  if (!uv__loop_alive(loop))
    return 0;

  do {
    uv__update_time(loop);
    uv__run_timers(loop);
    uv__run_idle(loop);
    uv__run_prepare(loop);
    uv__run_pending(loop);
    uv__io_poll(loop, (mode & UV_RUN_NOWAIT ? 0 : uv_backend_timeout(loop)));
    uv__run_check(loop);
    uv__run_closing_handles(loop);
    r = uv__loop_alive(loop);
  } while (r && !(mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)));

  return r;
}
Beispiel #5
0
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
  int timeout;
  int r;

  r = uv__loop_alive(loop);
  while (r != 0 && loop->stop_flag == 0) {
    UV_TICK_START(loop, mode);

    uv__update_time(loop);
    uv__run_timers(loop);
    uv__run_idle(loop);
    uv__run_prepare(loop);
    uv__run_pending(loop);

    timeout = 0;
    if ((mode & UV_RUN_NOWAIT) == 0)
      timeout = uv_backend_timeout(loop);

    uv__io_poll(loop, timeout);
    uv__run_check(loop);
    uv__run_closing_handles(loop);
    r = uv__loop_alive(loop);

    UV_TICK_STOP(loop, mode);

    if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
      break;
  }

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

  return r;
}
Beispiel #6
0
int uv_loop_alive(const uv_loop_t* loop) {
    return uv__loop_alive(loop);
}
Beispiel #7
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;
}