Пример #1
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;
}
Пример #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
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;
}
Пример #4
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;
}