void swTimeWheel_forward(swTimeWheel *tw, swReactor *reactor) { swHashMap *set = tw->wheel[tw->current]; tw->current = tw->current == tw->size - 1 ? 0 : tw->current + 1; swTraceLog(SW_TRACE_REACTOR, "current=%d.", tw->current); swConnection *conn; uint64_t fd; while (1) { conn = swHashMap_each_int(set, &fd); if (conn == NULL) { break; } conn->close_force = 1; conn->close_notify = 1; conn->close_wait = 1; conn->close_actively = 1; //notify to reactor thread if (conn->removed) { reactor->close(reactor, (int) fd); } else { reactor->set(reactor, fd, SW_FD_TCP | SW_EVENT_WRITE); } } }
void php_swoole_clear_all_timer() { if (!SwooleG.timer.map) { return; } uint64_t timer_id; //kill user process while (1) { swTimer_node *tnode = swHashMap_each_int(SwooleG.timer.map, &timer_id); if (tnode == NULL) { break; } if (tnode->type != SW_TIMER_TYPE_PHP) { continue; } php_swoole_del_timer(tnode TSRMLS_CC); swTimer_del(&SwooleG.timer, tnode); } }
int swTimer_select(swTimer *timer) { uint64_t key; swTimer_node *timer_node; int64_t now_ms = swTimer_get_ms(); if (now_ms < 0) { return SW_ERR; } if (timer->onTimer == NULL) { swWarn("timer->onTimer is NULL"); return SW_ERR; } do { //swWarn("timer foreach start\n----------------------------------------------"); timer_node = swHashMap_each_int(timer->list, &key); //hashmap empty if (timer_node == NULL) { break; } //swWarn("Timer=%ld|lasttime=%ld|now=%ld", key, timer_node->lasttime, now_ms); if (timer_node->lasttime < now_ms - timer_node->interval) { timer->onTimer(timer, timer_node->interval); timer_node->lasttime += timer_node->interval; } } while(timer_node); return SW_OK; }
int swTimer_select(swTimer *timer) { uint64_t key; swTimer_node *timer_node; struct timeval now; if (gettimeofday(&now, NULL) < 0) { swSysError("gettimeofday() failed."); return SW_ERR; } //swWarn("%d.%d", now.tv_sec, now.tv_usec); if (timer->onTimeout == NULL) { swWarn("timer->onTimeout is NULL"); return SW_ERR; } /** * timeout task list */ uint32_t now_ms = now.tv_sec * 1000 + now.tv_usec / 1000; swTimer_node *tmp = timer->root; while (tmp) { if (tmp->exec_msec > now_ms) { break; } else { timer->onTimeout(timer, tmp->data); timer->root = tmp->next; sw_free(tmp); tmp = timer->root; } } if (timer->onTimer == NULL) { swWarn("timer->onTimer is NULL"); return SW_ERR; } uint32_t interval = 0; do { //swWarn("timer foreach start\n----------------------------------------------"); timer_node = swHashMap_each_int(timer->list, &key); //hashmap empty if (timer_node == NULL) { break; } //the interval time(ms) interval = (now.tv_sec - timer_node->lasttime.tv_sec) * 1000 + (now.tv_usec - timer_node->lasttime.tv_usec) / 1000; /** * deviation 1ms */ if (interval >= timer_node->interval - 1) { memcpy(&timer_node->lasttime, &now, sizeof(now)); timer->onTimer(timer, timer_node); } } while (timer_node); return SW_OK; }