static int swEventTimer_add(swTimer *timer, int _msec, int interval, void *data) { swTimer_node *node = sw_malloc(sizeof(swTimer_node)); if (!node) { swSysError("malloc(%d) failed.", (int )sizeof(swTimer_node)); return SW_ERR; } int now_msec = swEventTimer_get_relative_msec(); if (now_msec < 0) { return SW_ERR; } node->data = data; node->exec_msec = now_msec + _msec; node->interval = interval ? _msec : 0; if (SwooleG.main_reactor->timeout_msec > _msec) { SwooleG.main_reactor->timeout_msec = _msec; } swTimer_node_insert(&timer->root, node); return SW_OK; }
long swTimer_addtimeout(swTimer *timer, int timeout_ms, void *data) { int new_interval = swoole_common_divisor(timeout_ms, timer->interval); if (new_interval < timer->interval) { swTimer_set(timer, new_interval); timer->interval = new_interval; } struct timeval now; if (gettimeofday(&now, NULL) < 0) { swWarn("gettimeofday() failed. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } uint32_t now_ms = now.tv_sec * 1000 + now.tv_usec / 1000; swTimer_node *node = sw_malloc(sizeof(swTimer_node)); if (node == NULL) { swWarn("malloc(%d) failed. Error: %s[%d]", (int ) sizeof(swTimer_node), strerror(errno), errno); return SW_ERR; } bzero(node, sizeof(swTimer_node)); node->data = data; node->exec_msec = now_ms + timeout_ms; node->id = timer->_next_id++; swTimer_node_insert(&timer->root, node); return node->id; }
static int swEventTimer_select(swTimer *timer) { int now_msec = swEventTimer_get_relative_msec(); if (now_msec < 0) { return SW_ERR; } swTimer_node *tmp = timer->root; while (tmp) { if (tmp->exec_msec > now_msec) { break; } else { if (tmp->interval > 0) { timer->onTimer(timer, tmp->interval); } else { timer->onTimeout(timer, tmp->data); } timer->root = tmp->next; if (timer->root) { timer->root->prev = NULL; } if (tmp->interval > 0) { tmp->exec_msec += tmp->interval; swTimer_node_insert(&SwooleG.timer.root, tmp); } else { sw_free(tmp); } tmp = timer->root; } } if (timer->root == NULL) { SwooleG.main_reactor->timeout_msec = -1; } else { SwooleG.main_reactor->timeout_msec = timer->root->exec_msec - now_msec; } return SW_OK; }