int swTimer_select(swTimer *timer) { int64_t now_msec = swTimer_get_relative_msec(); if (now_msec < 0) { return SW_ERR; } swTimer_node *tnode = NULL; swHeap_node *tmp; long timer_id; while ((tmp = swHeap_top(timer->heap))) { tnode = tmp->data; if (tnode->exec_msec > now_msec) { break; } timer_id = timer->_current_id = tnode->id; if (!tnode->remove) { tnode->callback(timer, tnode); } timer->_current_id = -1; //persistent timer if (tnode->interval > 0 && !tnode->remove) { while (tnode->exec_msec <= now_msec) { tnode->exec_msec += tnode->interval; } swHeap_change_priority(timer->heap, tnode->exec_msec, tmp); continue; } timer->num--; swHeap_pop(timer->heap); swHashMap_del_int(timer->map, timer_id); sw_free(tnode); } if (!tnode || !tmp) { timer->_next_msec = -1; timer->set(timer, -1); } else { timer->set(timer, tnode->exec_msec - now_msec); } return SW_OK; }
static swTimer_node* swTimer_add(swTimer *timer, int _msec, int interval, void *data, swTimerCallback callback) { swTimer_node *tnode = sw_malloc(sizeof(swTimer_node)); if (!tnode) { swSysError("malloc(%ld) failed.", sizeof(swTimer_node)); return NULL; } int64_t now_msec = swTimer_get_relative_msec(); if (now_msec < 0) { sw_free(tnode); return NULL; } tnode->data = data; tnode->type = SW_TIMER_TYPE_KERNEL; tnode->exec_msec = now_msec + _msec; tnode->interval = interval ? _msec : 0; tnode->remove = 0; tnode->callback = callback; tnode->round = timer->round; if (timer->_next_msec < 0 || timer->_next_msec > _msec) { timer->set(timer, _msec); timer->_next_msec = _msec; } tnode->id = timer->_next_id++; if (unlikely(tnode->id < 0)) { tnode->id = 1; timer->_next_id = 2; } timer->num++; tnode->heap_node = swHeap_push(timer->heap, tnode->exec_msec, tnode); if (tnode->heap_node == NULL) { sw_free(tnode); return NULL; } swTrace("id=%ld, exec_msec=%" PRId64 ", msec=%d, round=%" PRIu64, tnode->id, tnode->exec_msec, _msec, tnode->round); swHashMap_add_int(timer->map, tnode->id, tnode); return tnode; }
swTimer_node* swTimer_add(swTimer *timer, int _msec, int interval, void *data) { swTimer_node *tnode = sw_malloc(sizeof(swTimer_node)); if (!tnode) { swSysError("malloc(%ld) failed.", sizeof(swTimer_node)); return NULL; } int64_t now_msec = swTimer_get_relative_msec(); if (now_msec < 0) { return NULL; } tnode->data = data; tnode->exec_msec = now_msec + _msec; tnode->interval = interval ? _msec : 0; tnode->remove = 0; if (timer->_next_msec < 0 || timer->_next_msec > _msec) { timer->set(timer, _msec); timer->_next_msec = _msec; } tnode->id = timer->_next_id++; timer->num++; tnode->heap_node = swHeap_push(timer->heap, tnode->exec_msec, tnode); if (tnode->heap_node == NULL) { sw_free(tnode); return NULL; } return tnode; }
int swTimer_select(swTimer *timer) { int64_t now_msec = swTimer_get_relative_msec(); if (now_msec < 0) { return SW_ERR; } swTimer_node *tnode = NULL; swHeap_node *tmp; while ((tmp = swHeap_top(timer->heap))) { tnode = tmp->data; if (tnode->exec_msec > now_msec) { break; } //tick timer if (tnode->interval > 0) { timer->onTick(timer, tnode); if (!tnode->remove) { int64_t _now_msec = swTimer_get_relative_msec(); if (_now_msec <= 0) { tnode->exec_msec = now_msec + tnode->interval; } else if (tnode->exec_msec + tnode->interval < _now_msec) { tnode->exec_msec = _now_msec + tnode->interval; } else { tnode->exec_msec += tnode->interval; } swHeap_change_priority(timer->heap, tnode->exec_msec, tmp); continue; } } //after timer else { timer->onAfter(timer, tnode); } timer->num --; swHeap_pop(timer->heap); sw_free(tnode); } if (!tnode) { timer->_next_msec = -1; timer->set(timer, -1); } else { timer->set(timer, tnode->exec_msec - now_msec); } return SW_OK; }