void  protobuf_c_dispatch_remove_timer (ProtobufCDispatchTimer *timer)
{
  protobuf_c_boolean may_be_first;
  RealDispatch *d = timer->dispatch;

  /* ignore mid-notify removal */
  if (timer->func == NULL)
    return;

  may_be_first = d->base.timeout_usecs == timer->timeout_usecs
              && d->base.timeout_secs == timer->timeout_secs;

  GSK_RBTREE_REMOVE (GET_TIMER_TREE (d), timer);

  if (may_be_first)
    {
      if (d->timer_tree == NULL)
        d->base.has_timeout = 0;
      else
        {
          ProtobufCDispatchTimer *min;
          GSK_RBTREE_FIRST (GET_TIMER_TREE (d), min);
          d->base.timeout_secs = min->timeout_secs;
          d->base.timeout_usecs = min->timeout_usecs;
        }
    }
}
Ejemplo n.º 2
0
int main()
{
  TreeNode *tree = NULL;
  TreeNode *node;
  guint i;
  g_assert (!add_tree (&tree, 1));
  g_assert (!add_tree (&tree, 2));
  g_assert (!add_tree (&tree, 3));
  g_assert ( add_tree (&tree, 1));
  g_assert ( add_tree (&tree, 2));
  g_assert ( add_tree (&tree, 3));
  g_assert (!test_tree (&tree, 0));
  g_assert ( test_tree (&tree, 1));
  g_assert ( test_tree (&tree, 2));
  g_assert ( test_tree (&tree, 3));
  g_assert (!test_tree (&tree, 4));
  g_assert (!del_tree  (&tree, 0));
  g_assert ( del_tree  (&tree, 2));
  g_assert (!del_tree  (&tree, 4));
  g_assert (!test_tree (&tree, 0));
  g_assert ( test_tree (&tree, 1));
  g_assert (!test_tree (&tree, 2));
  g_assert ( test_tree (&tree, 3));
  g_assert (!test_tree (&tree, 4));
  g_assert ( add_tree (&tree, 1));
  g_assert (!add_tree (&tree, 2));
  g_assert ( add_tree (&tree, 3));
  g_assert ( del_tree  (&tree, 1));
  g_assert ( del_tree  (&tree, 2));
  g_assert ( del_tree  (&tree, 3));
  g_assert (tree == NULL);

  GSK_RBTREE_FIRST (TREE(&tree), node);
  g_assert (node == NULL);
  GSK_RBTREE_LAST (TREE(&tree), node);
  g_assert (node == NULL);

  /* Construct tree with odd numbers 1..999 inclusive */
  for (i = 1; i <= 999; i += 2)
    g_assert (!add_tree (&tree, i));

  GSK_RBTREE_FIRST (TREE(&tree), node);
  g_assert (node != NULL);
  g_assert (node->value == 1);
  GSK_RBTREE_LAST (TREE(&tree), node);
  g_assert (node != NULL);
  g_assert (node->value == 999);

  for (i = 1; i <= 999; i += 2)
    {
      g_assert (test_tree (&tree, i));
      g_assert (!test_tree (&tree, i+1));
    }
  for (i = 0; i <= 999; i++)
    {
      GSK_RBTREE_SUPREMUM_COMPARATOR (TREE(&tree), i, COMPARE_INT_WITH_TREE_NODE, node);
      g_assert (node);
      g_assert (node->value == (i%2)?i:(i+1));
    }
  GSK_RBTREE_SUPREMUM_COMPARATOR (TREE(&tree), 1000, COMPARE_INT_WITH_TREE_NODE, node);
  g_assert (node==NULL);
  for (i = 1; i <= 1000; i++)
    {
      TreeNode *node;
      GSK_RBTREE_INFIMUM_COMPARATOR (TREE(&tree), i, COMPARE_INT_WITH_TREE_NODE, node);
      g_assert (node);
      g_assert (node->value == (i%2)?i:(i-1));
    }
  GSK_RBTREE_INFIMUM_COMPARATOR (TREE(&tree), 0, COMPARE_INT_WITH_TREE_NODE, node);
  g_assert (node==NULL);
  for (i = 1; i <= 999; i += 2)
    g_assert (del_tree (&tree, i));

  /* random rbctree test */
  g_printerr ("Testing RBC-tree macros... ");
  for (i = 0; i < 1000; i++)
    test_random_rbcint_tree (10, TRUE);
  g_printerr (".");
  for (i = 0; i < 100; i++)
    test_random_rbcint_tree (100, TRUE);
  g_printerr (".");
  for (i = 0; i < 50; i++)
    {
      test_random_rbcint_tree (1000, FALSE);
      g_printerr (".");
    }
  for (i = 0; i < 5; i++)
    {
      test_random_rbcint_tree (10000, FALSE);
      g_printerr (".");
    }
  g_printerr (" done.\n");

  return 0;
}
void
protobuf_c_dispatch_dispatch (ProtobufCDispatch *dispatch,
                              size_t              n_notifies,
                              ProtobufC_FDNotify *notifies)
{
  RealDispatch *d = (RealDispatch *) dispatch;
  unsigned fd_max;
  unsigned i;
  struct timeval tv;

  /* Re-entrancy guard.  If this is triggerred, then
     you are calling protobuf_c_dispatch_dispatch (or _run)
     from a callback function.  That's not allowed. */
  protobuf_c_assert (!d->is_dispatching);
  d->is_dispatching = 1;

  gettimeofday (&tv, NULL);
  dispatch->last_dispatch_secs = tv.tv_sec;
  dispatch->last_dispatch_usecs = tv.tv_usec;

  fd_max = 0;
  for (i = 0; i < n_notifies; i++)
    if (fd_max < (unsigned) notifies[i].fd)
      fd_max = notifies[i].fd;
  ensure_fd_map_big_enough (d, fd_max);
  for (i = 0; i < n_notifies; i++)
    d->fd_map[notifies[i].fd].closed_since_notify_started = 0;
  for (i = 0; i < n_notifies; i++)
    {
      unsigned fd = notifies[i].fd;
      if (!d->fd_map[fd].closed_since_notify_started
       && d->fd_map[fd].notify_desired_index != -1)
        {
          unsigned nd_ind = d->fd_map[fd].notify_desired_index;
          unsigned events = d->base.notifies_desired[nd_ind].events & notifies[i].events;
          if (events != 0)
            d->callbacks[nd_ind].func (fd, events, d->callbacks[nd_ind].data);
        }
    }

  /* clear changes */
  for (i = 0; i < dispatch->n_changes; i++)
    d->fd_map[dispatch->changes[i].fd].change_index = -1;
  dispatch->n_changes = 0;

  /* handle idle functions */
  while (d->first_idle != NULL)
    {
      ProtobufCDispatchIdle *idle = d->first_idle;
      ProtobufCDispatchIdleFunc func = idle->func;
      void *data = idle->func_data;
      GSK_LIST_REMOVE_FIRST (GET_IDLE_LIST (d));

      idle->func = NULL;                /* set to NULL to render remove_idle a no-op */
      func (dispatch, data);

      idle->next = d->recycled_idles;
      d->recycled_idles = idle;
    }
  dispatch->has_idle = 0;

  /* handle timers */
  while (d->timer_tree != NULL)
    {
      ProtobufCDispatchTimer *min_timer;
      GSK_RBTREE_FIRST (GET_TIMER_TREE (d), min_timer);
      if (min_timer->timeout_secs < (unsigned long) tv.tv_sec
       || (min_timer->timeout_secs == (unsigned long) tv.tv_sec
        && min_timer->timeout_usecs <= (unsigned) tv.tv_usec))
        {
          ProtobufCDispatchTimerFunc func = min_timer->func;
          void *func_data = min_timer->func_data;
          GSK_RBTREE_REMOVE (GET_TIMER_TREE (d), min_timer);
          /* Set to NULL as a way to tell protobuf_c_dispatch_remove_timer()
             that we are in the middle of notifying */
          min_timer->func = NULL;
          min_timer->func_data = NULL;
          func (&d->base, func_data);
          free_timer (min_timer);
        }
      else
        {
          d->base.has_timeout = 1;
          d->base.timeout_secs = min_timer->timeout_secs;
          d->base.timeout_usecs = min_timer->timeout_usecs;
          break;
        }
    }
  if (d->timer_tree == NULL)
    d->base.has_timeout = 0;

  /* Finish reentrance guard. */
  d->is_dispatching = 0;
}