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; } } }
static gboolean del_tree (TreeNode **ptop, guint v) { TreeNode *found; GSK_RBTREE_LOOKUP_COMPARATOR (TREE(ptop), v, COMPARE_INT_WITH_TREE_NODE, found); if (found == NULL) return FALSE; GSK_RBTREE_REMOVE (TREE(ptop), found); gsk_mem_pool_fixed_free (&tree_node_pool, found); return TRUE; }
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; }