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);
    }
}
Esempio n. 3
0
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);
    }
}
Esempio n. 5
0
/*定时器事件超时处理*/
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);
    }
}
Esempio n. 6
0
/*删除定时器事件,但会执行相应的回调*/
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);
    }
}
Esempio n. 7
0
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);
}