Пример #1
0
/** @internal Main loop.
 *
 * The function @c su_port_run() waits for wait objects and the timers
 * associated with the port object.  When any wait object is signaled or
 * timer is expired, it invokes the callbacks, and returns waiting.
 *
 * The function @c su_port_run() runs until @c su_port_break() is called
 * from a callback.
 *
 * @param self     pointer to port object
 *
 */
void su_base_port_run(su_port_t *self)
{
  su_duration_t tout = 0, tout2 = 0;

  assert(su_port_own_thread(self));

  for (self->sup_running = 1; self->sup_running;) {
    tout = self->sup_max_defer;

    if (self->sup_prepoll)
      self->sup_prepoll(self->sup_pp_magic, self->sup_pp_root);

    if (self->sup_head)
      self->sup_vtable->su_port_getmsgs(self);

    if (self->sup_timers || self->sup_deferrable) {
      su_time_t now = su_now();
      su_timer_expire(&self->sup_timers, &tout, now);
      su_timer_expire(&self->sup_deferrable, &tout2, now);
    }

    if (!self->sup_running)
      break;

    if (self->sup_head)      /* if there are messages do a quick wait */
      tout = 0;

    self->sup_vtable->su_port_wait_events(self, tout);
  }
}
Пример #2
0
static
gboolean su_source_dispatch(GSource *gs,
			    GSourceFunc callback,
			    gpointer user_data)
{
  SuSource *ss = (SuSource *)gs;
  su_port_t *self = ss->ss_port;

  enter;

  if (self->sup_base->sup_head)
    su_base_port_getmsgs(self);

  if (self->sup_base->sup_timers || self->sup_base->sup_deferrable) {
    su_time_t now;
    GTimeVal  gtimeval;
    su_duration_t tout;

    tout = SU_DURATION_MAX;

    g_source_get_current_time(gs, &gtimeval);

    now.tv_sec = gtimeval.tv_sec + 2208988800UL;
    now.tv_usec = gtimeval.tv_usec;

    su_timer_expire(&self->sup_base->sup_timers, &tout, now);
    su_timer_expire(&self->sup_base->sup_deferrable, &tout, now);
  }

#if SU_HAVE_POLL
  {
    su_root_t *root;
    su_wait_t *waits = self->sup_waits;
    unsigned i, n = self->sup_n_waits;
    unsigned version = self->sup_registers;

    for (i = 0; i < n; i++) {
      if (waits[i].revents) {
	root = self->sup_wait_roots[i];
	self->sup_wait_cbs[i](root ? su_root_magic(root) : NULL,
			      &waits[i],
			      self->sup_wait_args[i]);
	/* Callback used su_register()/su_unregister() */
	if (version != self->sup_registers)
	  break;
      }
    }
  }
#endif

  if (!callback)
    return TRUE;

  return callback(user_data);
}
Пример #3
0
/** @internal Block until wait object is signaled or timeout.
 *
 * This function waits for wait objects and the timers associated with
 * the root object.  When any wait object is signaled or timer is
 * expired, it invokes the callbacks.
 *
 *   This function returns when a callback has been invoked or @c tout
 *   milliseconds is elapsed.
 *
 * @param self     pointer to port
 * @param tout     timeout in milliseconds
 *
 * @return
 *   Milliseconds to the next invocation of timer, or @c SU_WAIT_FOREVER if
 *   there are no active timers.
 */
su_duration_t su_base_port_step(su_port_t *self, su_duration_t tout)
{
  su_time_t now = su_now();

  assert(su_port_own_thread(self));

  if (self->sup_prepoll)
    self->sup_prepoll(self->sup_pp_magic, self->sup_pp_root);

  if (self->sup_head)
    self->sup_vtable->su_port_getmsgs(self);

  if (self->sup_timers)
    su_timer_expire(&self->sup_timers, &tout, now);

  /* XXX: why isn't the timeout ignored here? */
  if (self->sup_deferrable)
    su_timer_expire(&self->sup_deferrable, &tout, now);

  /* if there are messages do a quick wait */
  if (self->sup_head)
    tout = 0;

  if (self->sup_vtable->su_port_wait_events(self, tout))
    tout = 0;
  else
    tout = SU_WAIT_FOREVER;

  if (self->sup_head) {
    if (self->sup_vtable->su_port_getmsgs(self)) {
      /* Check for wait events that may have been generated by messages */
      if (self->sup_vtable->su_port_wait_events(self, 0))
	tout = 0;
    }
  }

  if (self->sup_timers || self->sup_deferrable) {
    su_duration_t tout2 = SU_WAIT_FOREVER;

    now = su_now();
    su_timer_expire(&self->sup_timers, &tout, now);
    su_timer_expire(&self->sup_deferrable, &tout2, now);

    if (tout == SU_WAIT_FOREVER && tout2 != SU_WAIT_FOREVER) {
      if (tout2 < self->sup_max_defer)
	tout2 = self->sup_max_defer;
      tout = tout2;
    }
  }

  if (self->sup_head)
    tout = 0;

  return tout;
}
Пример #4
0
/* This version can help tuning... */
void su_base_port_run_tune(su_port_t *self)
{
  int i;
  int timers = 0, messages = 0, events = 0;
  su_duration_t tout = 0, tout2 = 0;
  su_time_t started = su_now(), woken = started, bedtime = woken;

  assert(su_port_own_thread(self));

  for (self->sup_running = 1; self->sup_running;) {
    tout = self->sup_max_defer;

    timers = 0, messages = 0;

    if (self->sup_prepoll)
      self->sup_prepoll(self->sup_pp_magic, self->sup_pp_root);

    if (self->sup_head)
      messages = self->sup_vtable->su_port_getmsgs(self);

    if (self->sup_timers || self->sup_deferrable) {
      su_time_t now = su_now();
      timers =
	su_timer_expire(&self->sup_timers, &tout, now) +
	su_timer_expire(&self->sup_deferrable, &tout2, now);
    }

    if (!self->sup_running)
      break;

    if (self->sup_head)      /* if there are messages do a quick wait */
      tout = 0;

    bedtime = su_now();

    events = self->sup_vtable->su_port_wait_events(self, tout);

    woken = su_now();

    if (messages || timers || events)
      SU_DEBUG_1(("su_port_run(%p): %.6f: %u messages %u timers %u "
		  "events slept %.6f/%.3f\n",
		  self, su_time_diff(woken, started), messages, timers, events,
		  su_time_diff(woken, bedtime), tout * 1e-3));

    if (!self->sup_running)
      break;
  }
}