Esempio n. 1
0
// Wait for some event
bool event_poll(int32_t ms)
{
  bool timed_out;
  uv_run_mode run_mode = UV_RUN_ONCE;

  if (input_ready()) {
    // If there's a pending input event to be consumed, do it now
    return true;
  }

  input_start();
  timed_out = false;

  if (ms > 0) {
    // Timeout passed as argument to the timer
    timer.data = &timed_out;
    // We only start the timer after the loop is running, for that we
    // use an prepare handle(pass the interval as data to it)
    timer_prepare.data = &ms;
    uv_prepare_start(&timer_prepare, timer_prepare_cb);
  } else if (ms == 0) {
    // For ms == 0, we need to do a non-blocking event poll by
    // setting the run mode to UV_RUN_NOWAIT.
    run_mode = UV_RUN_NOWAIT;
  }

  do {
    // Run one event loop iteration, blocking for events if run_mode is
    // UV_RUN_ONCE
    uv_run(uv_default_loop(), run_mode);
  } while (
      // Continue running if ...
      !input_ready() &&   // we have no input
      kl_empty(event_queue) &&   // no events are waiting to be processed
      run_mode != UV_RUN_NOWAIT &&   // ms != 0
      !timed_out);  // we didn't get a timeout

  input_stop();

  if (ms > 0) {
    // Stop the timer
    uv_timer_stop(&timer);
  }

  return input_ready() || event_is_pending();
}
Esempio n. 2
0
// Wait for some event
bool event_poll(int32_t ms)
{
  uv_run_mode run_mode = UV_RUN_ONCE;

  if (input_ready()) {
    // If there's a pending input event to be consumed, do it now
    return true;
  }

  static int recursive = 0;

  if (!(recursive++)) {
    // Only needs to start the libuv handle the first time we enter here
    input_start();
  }

  uv_timer_t timer;
  uv_prepare_t timer_prepare;
  TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer};

  if (ms > 0) {
    uv_timer_init(uv_default_loop(), &timer);
    // This prepare handle that actually starts the timer
    uv_prepare_init(uv_default_loop(), &timer_prepare);
    // Timeout passed as argument to the timer
    timer.data = &timer_data;
    // We only start the timer after the loop is running, for that we
    // use a prepare handle(pass the interval as data to it)
    timer_prepare.data = &timer_data;
    uv_prepare_start(&timer_prepare, timer_prepare_cb);
  } else if (ms == 0) {
    // For ms == 0, we need to do a non-blocking event poll by
    // setting the run mode to UV_RUN_NOWAIT.
    run_mode = UV_RUN_NOWAIT;
  }

  do {
    // Run one event loop iteration, blocking for events if run_mode is
    // UV_RUN_ONCE
    uv_run(uv_default_loop(), run_mode);
    // Process immediate events outside uv_run since libuv event loop not
    // support recursion(processing events may cause a recursive event_poll
    // call)
    event_process(false);
  } while (
      // Continue running if ...
      !input_ready() &&   // we have no input
      !event_has_deferred() &&   // no events are waiting to be processed
      run_mode != UV_RUN_NOWAIT &&   // ms != 0
      !timer_data.timed_out);  // we didn't get a timeout

  if (!(--recursive)) {
    // Again, only stop when we leave the top-level invocation
    input_stop();
  }

  if (ms > 0) {
    // Ensure the timer-related handles are closed and run the event loop
    // once more to let libuv perform it's cleanup
    uv_close((uv_handle_t *)&timer, NULL);
    uv_close((uv_handle_t *)&timer_prepare, NULL);
    uv_run(uv_default_loop(), UV_RUN_NOWAIT);
    event_process(false);
  }

  return input_ready() || event_has_deferred();
}

bool event_has_deferred()
{
  return !kl_empty(get_queue(true));
}

// Push an event to the queue
void event_push(Event event, bool deferred)
{
  *kl_pushp(Event, get_queue(deferred)) = event;
}
Esempio n. 3
0
bool event_has_deferred(void)
{
  return deferred_events_allowed && !kl_empty(deferred_events);
}
Esempio n. 4
0
bool event_is_pending()
{
  return !kl_empty(event_queue);
}