Exemplo n.º 1
0
  static gboolean
log_writer_fd_check(GSource *source)
{
  LogWriterWatch *self = (LogWriterWatch *) source;
  gint64 num_elements = log_queue_get_length(self->writer->queue);

  if (self->error_suspend)
    return FALSE;

  if (num_elements && !log_writer_throttling(self->writer))
  {
    /* we have data to flush */
    if (self->flush_waiting_for_timeout)
    {
      GTimeVal tv;

      /* check if timeout elapsed */
      g_source_get_current_time(source, &tv);
      if (!(self->flush_target.tv_sec <= tv.tv_sec || (self->flush_target.tv_sec == tv.tv_sec && self->flush_target.tv_usec <= tv.tv_usec)))
        return FALSE;
      if ((self->writer->flags & LW_ALWAYS_WRITABLE))
        return TRUE;
    }
  }
  return !!(self->pollfd.revents & (G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_IN));
}
Exemplo n.º 2
0
/*
 * Event source function - get timeout time of the source.
 *  -1 means never timeout.
*/
static gboolean
hm_watch_prepare(GSource *source, gint *timeout)
{
    GTimeVal now;
    glong diff;
    HmWatch *watch;

    watch = (HmWatch*)source;
    if (!watch->buffer)
    {
        *timeout = -1;
        return FALSE;
    }

    g_source_get_current_time(source, &now);
    diff = hm_watch_time_val_diff(&watch->next_timeout, &now);
    if (diff <= 0)
    {
        *timeout = 0;
        return TRUE;
    }
    else
    {
        if (diff <= hm_connection_get_timeout(watch->conn))
        {
            *timeout = diff;
            return FALSE;
        }
        *timeout = 0;
        return TRUE;
    }
}
Exemplo n.º 3
0
static gboolean owl_timer_dispatch(GSource *source, GSourceFunc callback, gpointer user_data) {
  GList **timers = owl_global_get_timerlist(&g);
  GTimeVal now;

  /* TODO: In the far /far/ future, g_source_get_time is what the cool
   * kids use to get system monotonic time. */
  g_source_get_current_time(source, &now);

  /* FIXME: bother with millisecond accuracy now that we can? */
  while(*timers) {
    owl_timer *t = (*timers)->data;
    int remove = 0;

    if(t->time > now.tv_sec)
      break;

    /* Reschedule if appropriate */
    if(t->interval > 0) {
      t->time = now.tv_sec + t->interval;
      *timers = g_list_remove(*timers, t);
      *timers = g_list_insert_sorted(*timers, t,
                                     (GCompareFunc)_owl_select_timer_cmp);
    } else {
      remove = 1;
    }

    /* Do the callback */
    t->callback(t, t->data);
    if(remove) {
      owl_select_remove_timer(t);
    }
  }
  return TRUE;
}
Exemplo n.º 4
0
static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc callback, AVAHI_GCC_UNUSED gpointer userdata) {
    AvahiGLibPoll* g = (AvahiGLibPoll*) source;
    AvahiWatch *w;
    AvahiTimeout *next_timeout;

    g_assert(g);

    if ((next_timeout = find_next_timeout(g))) {
        GTimeVal now;
        struct timeval tvnow;
        g_source_get_current_time(source, &now);
        tvnow.tv_sec = now.tv_sec;
        tvnow.tv_usec = now.tv_usec;

        if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) < 0) {
            start_timeout_callback(next_timeout);
            return TRUE;
        }
    }

    for (w = g->watches; w; w = w->watches_next)
        if (w->pollfd.revents > 0) {
            assert(w->callback);
            w->callback(w, w->pollfd.fd, map_events_from_glib(w->pollfd.revents), w->userdata);
            w->pollfd.revents = 0;
            return TRUE;
        }

    return TRUE;
}
Exemplo n.º 5
0
static gboolean prepare_func(GSource *source, gint *timeout) {
    AvahiGLibPoll *g = (AvahiGLibPoll*) source;
    AvahiTimeout *next_timeout;

    g_assert(g);
    g_assert(timeout);

    if (g->watch_req_cleanup)
        cleanup_watches(g, 0);

    if (g->timeout_req_cleanup)
        cleanup_timeouts(g, 0);

    if ((next_timeout = find_next_timeout(g))) {
        GTimeVal now;
        struct timeval tvnow;
        AvahiUsec usec;

        g_source_get_current_time(source, &now);
        tvnow.tv_sec = now.tv_sec;
        tvnow.tv_usec = now.tv_usec;

        usec = avahi_timeval_diff(&next_timeout->expiry, &tvnow);

        if (usec <= 0) {
	   *timeout = 0;
            return TRUE;
	}

        *timeout = (gint) (usec / 1000);
    } else
        *timeout = -1;

    return FALSE;
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
osync_bool osync_queue_send_message_with_timeout(OSyncQueue *queue, OSyncQueue *replyqueue, OSyncMessage *message, unsigned int timeout, OSyncError **error)
{
  osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %u, %p)", __func__, queue, replyqueue, message, timeout, error);

  if (osync_message_get_handler(message)) {
    OSyncPendingMessage *pending = NULL;
    GTimeVal current_time;
    long long int id = 0;
    osync_assert(replyqueue);
    pending = osync_try_malloc0(sizeof(OSyncPendingMessage), error);
    if (!pending)
      goto error;

    /* g_sourcet_get_current_time used cached time ... hopefully faster then g_get_.._time() */
    g_source_get_current_time(queue->timeout_source, &current_time);

    id = gen_id(&current_time);
    osync_message_set_id(message, id);
    pending->id = id;
    osync_trace(TRACE_INTERNAL, "Setting id %lli for pending reply", id);

    if (timeout) {
      OSyncTimeoutInfo *toinfo = osync_try_malloc0(sizeof(OSyncTimeoutInfo), error);
      if (!toinfo)
        goto error;

      toinfo->expiration = current_time;
      toinfo->expiration.tv_sec += timeout;

      pending->timeout_info = toinfo;
    } else {
      osync_trace(TRACE_INTERNAL, "handler message got sent without timeout!: %s", osync_message_get_commandstr(message));
    }
		
    pending->callback = osync_message_get_handler(message);
    pending->user_data = osync_message_get_handler_data(message);
		
    g_mutex_lock(replyqueue->pendingLock);
    replyqueue->pendingReplies = g_list_append(replyqueue->pendingReplies, pending);
    g_mutex_unlock(replyqueue->pendingLock);
  }
	
  osync_message_ref(message);
  g_async_queue_push(queue->outgoing, message);

  g_main_context_wakeup(queue->context);

  osync_trace(TRACE_EXIT, "%s", __func__);
  return TRUE;

 error:
  osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error));
  return FALSE;
}
Exemplo n.º 8
0
static gboolean 
g_timeout_check (GSource  *source)
{
  GTimeVal current_time;
  GTimeoutSource *timeout_source = (GTimeoutSource *)source;

  g_source_get_current_time (source, &current_time);
  
  return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
	  ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
	   (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
}
Exemplo n.º 9
0
static gboolean
g_timeout_prepare  (GSource  *source,
		    gint     *timeout)
{
  glong sec;
  glong msec;
  GTimeVal current_time;
  
  GTimeoutSource *timeout_source = (GTimeoutSource *)source;

  g_source_get_current_time (source, &current_time);

  sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
  msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;

  /* We do the following in a rather convoluted fashion to deal with
   * the fact that we don't have an integral type big enough to hold
   * the difference of two timevals in millseconds.
   */
  if (sec < 0 || (sec == 0 && msec < 0))
    msec = 0;
  else
    {
      glong interval_sec = timeout_source->interval / 1000;
      glong interval_msec = timeout_source->interval % 1000;

      if (msec < 0)
	{
	  msec += 1000;
	  sec -= 1;
	}
      
      if (sec > interval_sec ||
	  (sec == interval_sec && msec > interval_msec))
	{
	  /* The system time has been set backwards, so we
	   * reset the expiration time to now + timeout_source->interval;
	   * this at least avoids hanging for long periods of time.
	   */
	  g_timeout_set_expiration (timeout_source, &current_time);
	  msec = MIN (G_MAXINT, timeout_source->interval);
	}
      else
	{
	  msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
	}
    }

  *timeout = (gint)msec;
  
  return msec == 0;
}
Exemplo n.º 10
0
static void
collect_timeout (gchar *sessionid, GstRTSPSession *sess, GstPoolSource *psrc)
{
  gint timeout;
  GTimeVal now;

  g_source_get_current_time ((GSource*)psrc, &now);

  timeout = gst_rtsp_session_next_timeout (sess, &now);
  g_message ("%p: next timeout: %d", sess, timeout);
  if (psrc->timeout == -1 || timeout < psrc->timeout)
    psrc->timeout = timeout;
}
Exemplo n.º 11
0
static gboolean
g_timeout_dispatch (GSource    *source,
		    GSourceFunc callback,
		    gpointer    user_data)
{
#if 0	// as GLib
  GTimeoutSource *timeout_source = (GTimeoutSource *)source;

  if (!callback)
    {
      g_warning ("Timeout source dispatched without callback\n"
		 "You must call g_source_set_callback().");
      return FALSE;
    }
 
  if (callback (user_data))
    {
      GTimeVal current_time;

      g_source_get_current_time (source, &current_time);
      g_timeout_set_expiration (timeout_source, &current_time);

      return TRUE;
    }
  else
    return FALSE;

#else
	GTimeoutSource *timeout_source = (GTimeoutSource *)source;
	GTimeVal current_time;

	g_source_get_current_time (source, &current_time);
    g_timeout_set_expiration (timeout_source, &current_time);

	return (callback (user_data)); 
#endif
}
Exemplo n.º 12
0
static gboolean owl_timer_check(GSource *source) {
  GList **timers = owl_global_get_timerlist(&g);
  GTimeVal now;

  /* TODO: In the far /far/ future, g_source_get_time is what the cool
   * kids use to get system monotonic time. */
  g_source_get_current_time(source, &now);

  /* FIXME: bother with millisecond accuracy now that we can? */
  if (*timers) {
    owl_timer *t = (*timers)->data;
    return t->time >= now.tv_sec;
  }
  return FALSE;
}
Exemplo n.º 13
0
static __inline__ void
hm_watch_update_time(HmWatch *watch, const GTimeVal *now)
{
    if (!now)
    {
        g_source_get_current_time((GSource*)watch,
            &watch->next_timeout);
    }
    else
    {
        memcpy(&watch->next_timeout, now, sizeof(*now));    
    }

    g_time_val_add(&watch->next_timeout,
        hm_connection_get_timeout(watch->conn) * 1000);
}
Exemplo n.º 14
0
  static gboolean
log_writer_fd_dispatch(GSource *source,
    GSourceFunc callback,
    gpointer user_data)
{
  LogWriterWatch *self = (LogWriterWatch *) source;
  gint64 num_elements = log_queue_get_length(self->writer->queue);

  if (self->pollfd.revents & (G_IO_HUP | G_IO_IN) && self->input_means_connection_broken)
  {
    msg_error("EOF occurred while idle",
        evt_tag_int("fd", log_proto_get_fd(self->proto)),
        NULL);
    log_writer_broken(self->writer, NC_CLOSE);
    return FALSE;
  }
  else if (self->pollfd.revents & (G_IO_ERR) && num_elements == 0)
  {
    msg_error("POLLERR occurred while idle",
        evt_tag_int("fd", log_proto_get_fd(self->proto)),
        NULL);
    log_writer_broken(self->writer, NC_WRITE_ERROR);
  }
  else if (num_elements)
  {
    if (!log_writer_flush_log(self->writer, self->proto))
    {
      self->error_suspend = TRUE;
      g_source_get_current_time(source, &self->error_suspend_target);
      g_time_val_add(&self->error_suspend_target, self->writer->options->time_reopen * 1e6);

      log_writer_broken(self->writer, NC_WRITE_ERROR);

      if (self->writer->source == (GSource *) self)
      {
        msg_notice("Suspending write operation because of an I/O error",
            evt_tag_int("fd", log_proto_get_fd(self->proto)),
            evt_tag_int("time_reopen", self->writer->options->time_reopen),
            NULL);
      }
      return TRUE;
    }
  }
  return TRUE;
}
Exemplo n.º 15
0
static glong
swfdec_iterate_get_msecs_to_next_event (GSource *source_)
{
  SwfdecIterateSource *source = (SwfdecIterateSource *) source_;
  GTimeVal now;
  glong diff;

  g_assert (source->player);
  diff = swfdec_player_get_next_event (source->player);
  if (diff == -1)
    return G_MAXLONG;
  diff *= source->speed;
  g_source_get_current_time (source_, &now);
  /* should really add to source->last instead of subtracting from now */
  g_time_val_add (&now, -diff * 1000);
  diff = my_time_val_difference (&source->last, &now);

  return diff;
}
Exemplo n.º 16
0
/** Prepare to wait - calculate time to next timer */
static
gboolean su_source_prepare(GSource *gs, gint *return_tout)
{
  SuSource *ss = (SuSource *)gs;
  su_port_t *self = ss->ss_port;
  su_duration_t tout = SU_WAIT_FOREVER;

  enter;

  if (self->sup_base->sup_head) {
    *return_tout = 0;
    return TRUE;
  }

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

    g_source_get_current_time(gs, &gtimeval);
    now.tv_sec = gtimeval.tv_sec + 2208988800UL;
    now.tv_usec = gtimeval.tv_usec;

    tout = su_timer_next_expires(&self->sup_base->sup_timers, now);

    if (self->sup_base->sup_deferrable) {
      su_duration_t tout_defer;

      tout_defer = su_timer_next_expires(&self->sup_base->sup_deferrable, now);

      if (tout_defer < self->sup_base->sup_max_defer)
        tout_defer = self->sup_base->sup_max_defer;

      if (tout > tout_defer)
        tout = tout_defer;
    }
  }

  *return_tout = (tout >= 0 && tout <= (su_duration_t)G_MAXINT)?
      (gint)tout : -1;

  return (tout == 0);
}
Exemplo n.º 17
0
static
gboolean _timeout_check(GSource *source)
{
  GList *p;
  GTimeVal current_time;
  OSyncTimeoutInfo *toinfo;
  OSyncPendingMessage *pending;

  OSyncQueue *queue = *((OSyncQueue **)(source + 1));

  g_source_get_current_time(source, &current_time);

  /* Search for the pending reply. We have to lock the
   * list since another thread might be duing the updates */
  g_mutex_lock(queue->pendingLock);

  for (p = queue->pendingReplies; p; p = p->next) {
    pending = p->data;

    if (!pending->timeout_info)
      continue;

    toinfo = pending->timeout_info;

    if (current_time.tv_sec >= toinfo->expiration.tv_sec 
        || (current_time.tv_sec == toinfo->expiration.tv_sec 
            && current_time.tv_usec >= toinfo->expiration.tv_usec)) {
      /* Unlock the pending lock since the messages might be sent during the callback */
      g_mutex_unlock(queue->pendingLock);

      return TRUE;
    }
  }
  /* Unlock the pending lock since the messages might be sent during the callback */
  g_mutex_unlock(queue->pendingLock);

  return FALSE;
}
Exemplo n.º 18
0
static gboolean owl_timer_prepare(GSource *source, int *timeout) {
  GList **timers = owl_global_get_timerlist(&g);
  GTimeVal now;

  /* TODO: In the far /far/ future, g_source_get_time is what the cool
   * kids use to get system monotonic time. */
  g_source_get_current_time(source, &now);

  /* FIXME: bother with millisecond accuracy now that we can? */
  if (*timers) {
    owl_timer *t = (*timers)->data;
    *timeout = t->time - now.tv_sec;
    if (*timeout <= 0) {
      *timeout = 0;
      return TRUE;
    }
    if (*timeout > 60 * 1000)
      *timeout = 60 * 1000;
  } else {
    *timeout = 60 * 1000;
  }
  return FALSE;
}
Exemplo n.º 19
0
/*
 * Event source function - check whether the condtion is
 *  satisfied.
*/
static gboolean
hm_watch_check(GSource *source)
{
    HmWatch *watch;
    GTimeVal now;
    G_ASSERT(source != NULL);

    watch = (HmWatch*)source;

    if (watch->r_fd.revents & READ_COND)
    {
        if (watch->buffer)
        {
            hm_watch_update_time(watch, NULL);
        }
        return TRUE;
    }

    if (watch->w_fd.revents & WRITE_COND)
        return TRUE;

    if (watch->buffer)
    {
        g_source_get_current_time(source, &now);
        if (hm_watch_clock_timeout(watch, &now))
        {
            hm_watch_update_time(watch, &now);
#ifdef USE_MONOTONIC_CLOCK
            if (hm_watch_time_drifted(watch, &now))
                return FALSE;
#endif
            return TRUE;
        }
    }

    return FALSE;
}
Exemplo n.º 20
0
static gboolean check_func(GSource *source) {
    AvahiGLibPoll *g = (AvahiGLibPoll*) source;
    AvahiWatch *w;
    AvahiTimeout *next_timeout;

    g_assert(g);

    if ((next_timeout = find_next_timeout(g))) {
        GTimeVal now;
        struct timeval tvnow;
        g_source_get_current_time(source, &now);
        tvnow.tv_sec = now.tv_sec;
        tvnow.tv_usec = now.tv_usec;

        if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) <= 0)
            return TRUE;
    }

    for (w = g->watches; w; w = w->watches_next)
        if (w->pollfd.revents > 0)
            return TRUE;

    return FALSE;
}
Exemplo n.º 21
0
static
gboolean _timeout_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
{
  GList *p;
  OSyncPendingMessage *pending;
  OSyncTimeoutInfo *toinfo;
  OSyncQueue *queue = NULL;
  GTimeVal current_time;

  osync_trace(TRACE_INTERNAL, "%s(%p)", __func__, user_data);

  queue = *((OSyncQueue **)(source + 1));

  g_source_get_current_time (source, &current_time);

  /* Search for the pending reply. We have to lock the
   * list since another thread might be duing the updates */
  g_mutex_lock(queue->pendingLock);

  for (p = queue->pendingReplies; p; p = p->next) {
    pending = p->data;

    if (!pending->timeout_info)
      continue;

    toinfo = pending->timeout_info;

    if (current_time.tv_sec == toinfo->expiration.tv_sec ||
        (current_time.tv_sec >= toinfo->expiration.tv_sec 
         && current_time.tv_usec >= toinfo->expiration.tv_usec)) {
      OSyncError *error = NULL;
      OSyncError *timeouterr = NULL;
      OSyncMessage *errormsg = NULL;

      /* Call the callback of the pending message */
      osync_assert(pending->callback);
      osync_error_set(&timeouterr, OSYNC_ERROR_IO_ERROR, "Timeout.");
      errormsg = osync_message_new_errorreply(NULL, timeouterr, &error);
      osync_error_unref(&timeouterr);

      /* Remove first the pending message!
         To avoid that _incoming_dispatch catchs this message
         when we're releasing the lock. If _incoming_dispatch
         would catch this message, the pending callback
         gets called twice! */

      queue->pendingReplies = g_list_remove(queue->pendingReplies, pending);
      /* Unlock the pending lock since the messages might be sent during the callback */
      g_mutex_unlock(queue->pendingLock);

      pending->callback(errormsg, pending->user_data);
      if (errormsg != NULL)
        osync_message_unref(errormsg);

      // TODO: Refcounting for OSyncPendingMessage
      g_free(pending->timeout_info);
      g_free(pending);

      /* Lock again, to keep the iteration of the pendingReplies list atomic. */
      g_mutex_lock(queue->pendingLock);

      break;
    }
  }
	
  g_mutex_unlock(queue->pendingLock);

  return TRUE;
}
Exemplo n.º 22
0
void main_loop_test()
{
	GMainContext *default_context;
	int depth;
	int id;
	GTimeVal time ={0,};
	int user_data = 0,fd_data = 0;
	GPollFD pollfd;
	GSource *source3;

	GSourceFuncs SourceFuncs =
	{
		prepare,
		check,
		dispatch,
		NULL
	};

	GSourceFuncs fd_SourceFuncs =
	{
		fd_prepare,
		fd_check,
		fd_dispatch,
		NULL
	};

	e1_complete = FALSE;
	e2_complete = FALSE;

	pipe(fd);

	pollfd.fd = fd[0];
	pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
	pollfd.revents = 0;

	pthread_create(&thread1, NULL, thread_function, NULL);

	context = g_main_context_new();

	//g_main_context_add_poll(context,&pollfd,0);

	source1 = g_source_new(&SourceFuncs,sizeof(GSource));
	g_source_set_callback(source1,(GSourceFunc)my_callback,&user_data,NULL);

	id = g_source_attach(source1,context);

	g_assert(g_source_get_id(source1) == id);

	g_source_set_priority(source1,0);

	g_assert(g_source_get_priority(source1) == 0);

	loop = g_main_loop_new(context, FALSE);

	default_context = g_main_loop_get_context(loop);

	//checks g_main_loop_get_context
	g_assert(default_context == context);

	//checks g_main_loop_is_running
	g_assert(g_main_loop_is_running(loop) == FALSE);

	depth = g_main_depth();

	//checks g_main_depth
	g_assert(depth == 0);

	g_source_get_current_time(source1,&time);

	g_assert(time.tv_usec > 0);

	g_source_set_can_recurse(source1,TRUE);

	g_assert(g_source_get_can_recurse(source1) == TRUE);

	source2 = g_source_new(&fd_SourceFuncs,sizeof(GSource));
	g_source_set_callback(source2,(GSourceFunc)fd_callback,&fd_data,NULL);
	g_source_add_poll(source2,&pollfd);

	g_source_remove_poll(source2,&pollfd);

	// checks g_source_remove_poll
	g_assert(source2->poll_fds == NULL);

	g_source_add_poll(source2,&pollfd);

	// checks whether g_source_add_poll is successful.
	// one more check is done in fd_callback.
	// If that function is callled we are sure that add poll was successful
	g_assert(source2->poll_fds->data == &pollfd);

	source3 = g_source_ref(source2);

	g_assert(source3 == source2 && source2->ref_count == 2);

	g_source_unref(source3);

	id = g_source_attach(source2,context);

	//checks g_main_context_pending
	g_assert(g_main_context_pending(context));

	g_main_loop_run(loop);

	// ref is called here. Thats why two unrefs are called. If the 2nd unref is
	// callled with the unref, code should crash
	g_main_loop_ref(loop);

	g_main_loop_unref(loop);

	g_main_loop_unref(loop);

	//checks the number of times the call back function is called
	g_assert(user_data == 100);

	// checks whether set poll was successful and call back for the same
	// was called
	g_assert(fd_data == 1);
}
Exemplo n.º 23
0
/*
 * master_clock_next_frame_delay:
 * @master_clock: a #ClutterMasterClock
 *
 * Computes the number of delay before we need to draw the next frame.
 *
 * Return value: -1 if there is no next frame pending, otherwise the
 *  number of millseconds before the we need to draw the next frame
 */
static gint
master_clock_next_frame_delay (ClutterMasterClock *master_clock)
{
  gint64 now, next;

  if (!master_clock_is_running (master_clock))
    return -1;

  /* When we have sync-to-vblank, we count on swap-buffer requests (or
   * swap-buffer-complete events if supported in the backend) to throttle our
   * frame rate so no additional delay is needed to start the next frame.
   *
   * If the master-clock has become idle due to no timeline progression causing
   * redraws then we can no longer rely on vblank synchronization because the
   * last real stage update/redraw may have happened a long time ago and so we
   * fallback to polling for timeline progressions every 1/frame_rate seconds.
   *
   * (NB: if there aren't even any timelines running then the master clock will
   * be completely stopped in master_clock_is_running())
   */
  if (clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK) &&
      !master_clock->idle)
    {
      CLUTTER_NOTE (SCHEDULER, "vblank available and updated stages");
      return 0;
    }

  if (master_clock->prev_tick == 0)
    {
      /* If we weren't previously running, then draw the next frame
       * immediately
       */
      CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
      return 0;
    }

  /* Otherwise, wait at least 1/frame_rate seconds since we last
   * started a frame
   */
#if GLIB_CHECK_VERSION (2, 27, 3)
  now = g_source_get_time (master_clock->source);
#else
  {
    GTimeVal source_time;
    g_source_get_current_time (master_clock->source, &source_time);
    now = source_time.tv_sec * 1000000L + source_time.tv_usec;
  }
#endif

  next = master_clock->prev_tick;

  /* If time has gone backwards then there's no way of knowing how
     long we should wait so let's just dispatch immediately */
  if (now <= next)
    {
      CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");

      return 0;
    }

  next += (1000000L / clutter_get_default_frame_rate ());

  if (next <= now)
    {
      CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
                    1000000L / (gulong) clutter_get_default_frame_rate ());

      return 0;
    }
  else
    {
      CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
                   (next - now) / 1000);

      return (next - now) / 1000;
    }
}
Exemplo n.º 24
0
static gboolean
clutter_clock_dispatch (GSource     *source,
                        GSourceFunc  callback,
                        gpointer     user_data)
{
  ClutterClockSource *clock_source = (ClutterClockSource *) source;
  ClutterMasterClock *master_clock = clock_source->master_clock;
  ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
  gboolean stages_updated = FALSE;
  GSList *stages, *l;

  CLUTTER_STATIC_TIMER (master_dispatch_timer,
                        "Mainloop",
                        "Master Clock",
                        "Master clock dispatch",
                        0);
  CLUTTER_STATIC_TIMER (master_event_process,
                        "Master Clock",
                        "Event Processing",
                        "The time spent processing events on all stages",
                        0);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_dispatch_timer);

  CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");

  clutter_threads_enter ();

  /* Get the time to use for this frame */
#if GLIB_CHECK_VERSION (2, 27, 3)
  master_clock->cur_tick = g_source_get_time (source);
#else
  {
    GTimeVal source_time;
    g_source_get_current_time (source, &source_time);
    master_clock->cur_tick = source_time.tv_sec * 1000000L
                           + source_time.tv_usec;
  }
#endif

  /* We need to protect ourselves against stages being destroyed during
   * event handling
   */
  stages = clutter_stage_manager_list_stages (stage_manager);
  g_slist_foreach (stages, (GFunc) g_object_ref, NULL);

  CLUTTER_TIMER_START (_clutter_uprof_context, master_event_process);

  master_clock->idle = FALSE;

  /* Process queued events */
  for (l = stages; l != NULL; l = l->next)
    {
      /* NB: If a stage is busy waiting for a swap-buffers completion then
       * we don't process its events so we can maximize the benefits of
       * motion compression, and avoid multiple picks per frame.
       */
      if (_clutter_stage_get_pending_swaps (l->data) == 0)
        _clutter_stage_process_queued_events (l->data);
    }

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);

  _clutter_master_clock_advance (master_clock);

  _clutter_run_repaint_functions ();

  /* Update any stage that needs redraw/relayout after the clock
   * is advanced.
   */
  for (l = stages; l != NULL; l = l->next)
    {
      /* If a stage has a swap-buffers pending we don't want to draw to it
       * in case the driver may block the CPU while it waits for the next
       * backbuffer to become available.
       *
       * TODO: We should be able to identify if we are running triple or N
       * buffered and in these cases we can still draw if there is 1 swap
       * pending so we can hopefully always be ready to swap for the next
       * vblank and really match the vsync frequency.
       */
      if (_clutter_stage_get_pending_swaps (l->data) == 0)
        stages_updated |= _clutter_stage_do_update (l->data);
    }

  /* The master clock goes idle if no stages were updated and falls back
   * to polling for timeline progressions... */
  if (!stages_updated)
    master_clock->idle = TRUE;

  g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
  g_slist_free (stages);

  master_clock->prev_tick = master_clock->cur_tick;

  clutter_threads_leave ();

  CLUTTER_TIMER_STOP (_clutter_uprof_context, master_dispatch_timer);

  return TRUE;
}
Exemplo n.º 25
0
  static gboolean
log_writer_fd_prepare(GSource *source,
    gint *timeout)
{
  LogWriterWatch *self = (LogWriterWatch *) source;
  gint64 num_elements = log_queue_get_length(self->writer->queue);
  GTimeVal now;
  GIOCondition proto_cond;

  self->pollfd.events = G_IO_ERR;
  self->pollfd.revents = 0;

  g_source_get_current_time(source, &now);
  if (log_proto_prepare(self->proto, &self->pollfd.fd, &proto_cond, timeout))
    return TRUE;

  /* recalculate buckets */

  if (self->writer->options->throttle > 0)
  {
    gint64 diff;
    gint new_buckets;

    /* throttling is enabled, calculate new buckets */
    if (self->last_throttle_check.tv_sec != 0)
    {
      diff = g_time_val_diff(&now, &self->last_throttle_check);
    }
    else
    {
      diff = 0;
      self->last_throttle_check = now;
    }
    new_buckets = (self->writer->options->throttle * diff) / G_USEC_PER_SEC;
    if (new_buckets)
    {

      /* if new_buckets is zero, we don't save the current time as
       * last_throttle_check. The reason is that new_buckets could be
       * rounded to zero when only a minimal interval passes between
       * poll iterations.
       */
      self->writer->throttle_buckets = MIN(self->writer->options->throttle, self->writer->throttle_buckets + new_buckets);
      self->last_throttle_check = now;
    }
  }

  if (G_UNLIKELY(self->error_suspend))
  {
    *timeout = g_time_val_diff(&self->error_suspend_target, &now) / 1000;
    if (*timeout <= 0)
    {
      msg_notice("Error suspend timeout has elapsed, attempting to write again",
          evt_tag_int("fd", log_proto_get_fd(self->proto)),
          NULL);
      self->error_suspend = FALSE;
      *timeout = -1;
    }
    else
    {
      return FALSE;
    }
  }

  if ((self->writer->options->flush_lines == 0 && (!log_writer_throttling(self->writer) && num_elements != 0)) ||
      (self->writer->options->flush_lines > 0  && (!log_writer_throttling(self->writer) && num_elements >= self->writer->options->flush_lines)))
  {
    /* we need to flush our buffers */
    self->pollfd.events |= proto_cond;
  }
  else if (num_elements && !log_writer_throttling(self->writer))
  {
    /* our buffer does not contain enough elements to flush, but we do not
     * want to wait more than flush_timeout time */

    if (!self->flush_waiting_for_timeout)
    {
      /* start waiting */

      *timeout = self->writer->options->flush_timeout;
      g_source_get_current_time(source, &self->flush_target);
      g_time_val_add(&self->flush_target, *timeout * 1000);
      self->flush_waiting_for_timeout = TRUE;
    }
    else
    {
      glong to = g_time_val_diff(&self->flush_target, &now) / 1000;
      if (to <= 0)
      {
        /* timeout elapsed, start polling again */
        if (self->writer->flags & LW_ALWAYS_WRITABLE)
          return TRUE;
        self->pollfd.events = proto_cond;
      }
      else
      {
        *timeout = to;
      }
    }
    return FALSE;
  }
  else
  {
    if (num_elements && log_writer_throttling(self->writer))
    {
      /* we are unable to send because of throttling, make sure that we
       * wake up when the rate limits lets us send at least 1 message */
      *timeout = (1000 / self->writer->options->throttle) + 1;
      msg_debug("Throttling output", 
          evt_tag_int("wait", *timeout), 
          NULL);
    }
  }

  if (self->writer->flags & LW_DETECT_EOF && (self->pollfd.events & G_IO_IN) == 0)
  {
    self->pollfd.events |= G_IO_HUP | G_IO_IN;
    self->input_means_connection_broken = TRUE;
  }
  else
  {
    self->input_means_connection_broken = FALSE;
  }

  self->flush_waiting_for_timeout = FALSE;

  if ((self->pollfd.events & G_IO_OUT) && (self->writer->flags & LW_ALWAYS_WRITABLE))
  {
    self->pollfd.revents = G_IO_OUT;
    return TRUE;
  }
  return FALSE;
}
Exemplo n.º 26
0
static gboolean
log_reader_fd_check(GSource *source)
{
  LogReaderWatch *self = (LogReaderWatch *) source;
 
  if (!log_source_free_to_send(&self->reader->super))
    return FALSE;

  if (self->reader->options->follow_freq > 0)
    {
      struct stat st, followed_st;
      off_t pos = -1;
      gint fd = log_proto_get_fd(self->reader->proto);

      /* FIXME: this is a _HUGE_ layering violation... */
      if (fd >= 0)
	{
	  pos = lseek(fd, 0, SEEK_CUR);      
	  if (pos == (off_t) -1)
	    {
	      msg_error("Error invoking seek on followed file",
			evt_tag_errno("error", errno),
			NULL);
	      return FALSE;
	    }

	  if (fstat(fd, &st) < 0)
	    {
              if (errno == ESTALE)
                {
                  msg_trace("log_reader_fd_check file moved ESTALE",
                            evt_tag_str("follow_filename",self->reader->follow_filename),
                            NULL);
                  log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self);
                  return FALSE;
                }
              else
                {
                  msg_error("Error invoking fstat() on followed file",
                            evt_tag_errno("error", errno),
                            NULL);
                  return FALSE;
                }
	    }

          msg_trace("log_reader_fd_check",
              	    evt_tag_int("pos", pos),
                    evt_tag_int("size", st.st_size),
		    NULL);

	  if (pos < st.st_size)
            {
	      return TRUE;
            }
          else if (pos == st.st_size)
            {
              log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_EOF, self);
            }
          else if (pos > st.st_size)
            { 
              /* reopen the file */
              log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self);
            }
	} 
        
      if (self->reader->follow_filename && stat(self->reader->follow_filename, &followed_st) != -1)
        {
          if (fd < 0 || (st.st_ino != followed_st.st_ino && followed_st.st_size > 0))
            {
              msg_trace("log_reader_fd_check file moved eof",
                        evt_tag_int("pos", pos),
                        evt_tag_int("size", followed_st.st_size),
                        evt_tag_str("follow_filename",self->reader->follow_filename),
                        NULL);
              /* file was moved and we are at EOF, follow the new file */
              log_pipe_notify(self->reader->control, &self->reader->super.super, NC_FILE_MOVED, self);
            }
        }
      else if (self->reader->follow_filename)
        {
          GTimeVal now;

          g_source_get_current_time(source, &now);
          if (g_time_val_diff(&now, &self->last_follow_freq_check) > self->reader->options->follow_freq * 1000)
            {
              msg_verbose("Follow mode file still does not exist",
                          evt_tag_str("filename", self->reader->follow_filename),
                          NULL);
              self->last_follow_freq_check = now;
            }
        }
      return FALSE;
    }
    
  return !!(self->pollfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP));
}