static void __agent_schedule_abs(struct ice_agent *ag, const struct timeval *tv) { struct timeval nxt; long long diff; if (!ag) { ilog(LOG_ERR, "ice ag is NULL"); return; } nxt = *tv; mutex_lock(&ice_agents_timers_lock); if (ag->last_run.tv_sec) { /* make sure we don't run more often than we should */ diff = timeval_diff(&nxt, &ag->last_run); if (diff < TIMER_RUN_INTERVAL * 1000) timeval_add_usec(&nxt, TIMER_RUN_INTERVAL * 1000 - diff); } if (ag->next_check.tv_sec && timeval_cmp(&ag->next_check, &nxt) <= 0) goto nope; /* already scheduled sooner */ if (!g_tree_remove(ice_agents_timers, ag)) obj_hold(ag); /* if it wasn't removed, we make a new reference */ ag->next_check = nxt; g_tree_insert(ice_agents_timers, ag, ag); cond_broadcast(&ice_agents_timers_cond); nope: mutex_unlock(&ice_agents_timers_lock); }
void timerthread_obj_schedule_abs_nl(struct timerthread_obj *tt_obj, const struct timeval *tv) { if (!tt_obj) return; ilog(LOG_DEBUG, "scheduling timer object at %llu.%06lu", (unsigned long long) tv->tv_sec, (unsigned long) tv->tv_usec); struct timerthread *tt = tt_obj->tt; if (tt_obj->next_check.tv_sec && timeval_cmp(&tt_obj->next_check, tv) <= 0) return; /* already scheduled sooner */ if (!g_tree_remove(tt->tree, tt_obj)) obj_hold(tt_obj); /* if it wasn't removed, we make a new reference */ tt_obj->next_check = *tv; g_tree_insert(tt->tree, tt_obj, tt_obj); cond_broadcast(&tt->cond); }
int poller_poll(struct poller *p, int timeout) { int ret, i; struct poller_item_int *it; struct epoll_event evs[128], *ev, e; if (!p) return -1; mutex_lock(&p->lock); ret = -1; if (!p->items || !p->items_size) goto out; mutex_unlock(&p->lock); errno = 0; ret = epoll_wait(p->fd, evs, sizeof(evs) / sizeof(*evs), timeout); mutex_lock(&p->lock); if (errno == EINTR) ret = 0; if (ret == 0) ret = 0; if (ret <= 0) goto out; gettimeofday(&g_now, NULL); for (i = 0; i < ret; i++) { ev = &evs[i]; if (ev->data.fd < 0) continue; it = (ev->data.fd < p->items_size) ? p->items[ev->data.fd] : NULL; if (!it) continue; obj_hold(it); mutex_unlock(&p->lock); if (it->error) { it->item.closed(it->item.fd, it->item.obj, it->item.uintp); goto next; } if ((ev->events & (POLLERR | POLLHUP))) it->item.closed(it->item.fd, it->item.obj, it->item.uintp); else if ((ev->events & POLLOUT)) { mutex_lock(&p->lock); it->blocked = 0; ZERO(e); e.events = epoll_events(NULL, it); e.data.fd = it->item.fd; if (epoll_ctl(p->fd, EPOLL_CTL_MOD, it->item.fd, &e)) abort(); mutex_unlock(&p->lock); it->item.writeable(it->item.fd, it->item.obj, it->item.uintp); } else if ((ev->events & POLLIN)) it->item.readable(it->item.fd, it->item.obj, it->item.uintp); else if (!ev->events) goto next; else abort(); next: obj_put(it); mutex_lock(&p->lock); } out: mutex_unlock(&p->lock); return ret; }