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; } } }
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; }