static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) { ngx_int_t rc; ngx_event_t *e; ev->active = 0; ev->disabled = 0; ngx_mutex_lock(list_mutex); if (ev->index < nchanges && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1) == (uintptr_t) ev) { ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent deleted: %d: ft:%i", ngx_event_ident(ev->data), event); /* if the event is still not passed to a kernel we will not pass it */ nchanges--; if (ev->index < nchanges) { e = (ngx_event_t *) ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1); change_list[ev->index] = change_list[nchanges]; e->index = ev->index; } ngx_mutex_unlock(list_mutex); return NGX_OK; } /* * when the file descriptor is closed the kqueue automatically deletes * its filters so we do not need to delete explicity the event * before the closing the file descriptor. */ if (flags & NGX_CLOSE_EVENT) { ngx_mutex_unlock(list_mutex); return NGX_OK; } if (flags & NGX_DISABLE_EVENT) { ev->disabled = 1; } else { flags |= EV_DELETE; } rc = ngx_kqueue_set_event(ev, event, flags); ngx_mutex_unlock(list_mutex); return rc; }
// 遍历定时器红黑树,找出所有过期的事件,调用handler处理超时 void ngx_event_expire_timers(void) { ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; // 红黑树的哨兵 sentinel = ngx_event_timer_rbtree.sentinel; for ( ;; ) { // 红黑树的根 root = ngx_event_timer_rbtree.root; // 红黑树已经空 if (root == sentinel) { return; } // 取红黑树的最小节点 node = ngx_rbtree_min(root, sentinel); /* node->key > ngx_current_time */ // 与当前时间进行比较,>0即还没有超时 // 没有了超时事件,循环退出 if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) { return; } // 此事件已经超时 // 通过offsetof获得事件对象 ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer del: %d: %M", ngx_event_ident(ev->data), ev->timer.key); // 事件从红黑树里移除 ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; ev->timer.parent = NULL; #endif // 定时器标志清零 ev->timer_set = 0; // 设置超时标志 ev->timedout = 1; // 调用事件的handler,里面检查timedout标志处理超时 ev->handler(ev); } }
static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) { ngx_int_t rc; #if 0 ngx_event_t *e; ngx_connection_t *c; #endif ev->active = 1; ev->disabled = 0; ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0; #if 0 if (ev->index < nchanges && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1) == (uintptr_t) ev) { if (change_list[ev->index].flags == EV_DISABLE) { /* * if the EV_DISABLE is still not passed to a kernel * we will not pass it */ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent activated: %d: ft:%i", ngx_event_ident(ev->data), event); if (ev->index < --nchanges) { e = (ngx_event_t *) ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1); change_list[ev->index] = change_list[nchanges]; e->index = ev->index; } return NGX_OK; } c = ev->data; ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "previous event on #%d were not passed in kernel", c->fd); return NGX_ERROR; } #endif rc = ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags); return rc; }
// 取消定时器,调用handler处理 void ngx_event_cancel_timers(void) { ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; // 红黑树的哨兵 sentinel = ngx_event_timer_rbtree.sentinel; for ( ;; ) { // 红黑树的根 root = ngx_event_timer_rbtree.root; // 红黑树已经空 if (root == sentinel) { return; } // 取红黑树的最小节点 node = ngx_rbtree_min(root, sentinel); // 通过offsetof获得事件对象 ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); // 事件不能被取消 if (!ev->cancelable) { return; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer cancel: %d: %M", ngx_event_ident(ev->data), ev->timer.key); // 事件从红黑树里移除 ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; ev->timer.parent = NULL; #endif // 定时器标志清零 ev->timer_set = 0; // 调用事件的handler ev->handler(ev); } }
/*定时器事件超时处理*/ void ngx_event_expire_timers(void) { ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; sentinel = ngx_event_timer_rbtree.sentinel; for ( ;; ) { root = ngx_event_timer_rbtree.root; if (root == sentinel) { return; } node = ngx_rbtree_min(root, sentinel); /* node->key > ngx_current_time */ if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) { return; } //获取当前定时器对应的事件控制块 ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer del: %d: %M", ngx_event_ident(ev->data), ev->timer.key); ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; ev->timer.parent = NULL; #endif ev->timer_set = 0; ev->timedout = 1; //调用定时器事件的超时处理函数 ev->handler(ev); } }
/*删除定时器事件,但会执行相应的回调*/ void ngx_event_cancel_timers(void) { ngx_event_t *ev; ngx_rbtree_node_t *node, *root, *sentinel; sentinel = ngx_event_timer_rbtree.sentinel; for ( ;; ) { root = ngx_event_timer_rbtree.root; if (root == sentinel) { return; } node = ngx_rbtree_min(root, sentinel); ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); /*如果事件不能取消,直接返回*/ if (!ev->cancelable) { return; } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer cancel: %d: %M", ngx_event_ident(ev->data), ev->timer.key); /*从定时器红黑树中删除这个事件*/ ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; ev->timer.parent = NULL; #endif /*将标志位清零*/ ev->timer_set = 0; /*调用事件处理函数*/ ev->handler(ev); } }
void ngx_event_expire_timers(ngx_msec_t timer) { ngx_event_t *ev; ngx_rbtree_t *node; if (timer < 0) { /* avoid the endless loop if the time goes backward for some reason */ timer = 0; } for ( ;; ) { if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) { return; } if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) { return; } node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree, &ngx_event_timer_sentinel); if (node->key <= (ngx_msec_t) (ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION) { ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, rbtree_key)); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, "event timer del: %d: %d", ngx_event_ident(ev->data), ev->rbtree_key); ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree, &ngx_event_timer_sentinel, (ngx_rbtree_t *) &ev->rbtree_key); ngx_mutex_unlock(ngx_event_timer_mutex); #if (NGX_DEBUG) ev->rbtree_left = NULL; ev->rbtree_right = NULL; ev->rbtree_parent = NULL; #endif ev->timer_set = 0; ev->timedout = 1; ev->event_handler(ev); continue; } break; } ngx_mutex_unlock(ngx_event_timer_mutex); }