static ngx_int_t
ngx_kqueue_notify_init(ngx_log_t *log)
{
    notify_kev.ident = 0;
    notify_kev.filter = EVFILT_USER;
    notify_kev.data = 0;
    notify_kev.flags = EV_ADD|EV_CLEAR;
    notify_kev.fflags = 0;
    notify_kev.udata = 0;

    if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                      "kevent(EVFILT_USER, EV_ADD) failed");
        return NGX_ERROR;
    }

    notify_event.active = 1;
    notify_event.log = log;

    notify_kev.flags = 0;
    notify_kev.fflags = NOTE_TRIGGER;
    notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) &notify_event);

    return NGX_OK;
}
static ngx_int_t
ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
{
    struct kevent     *kev;
    struct timespec    ts;
    ngx_connection_t  *c;
    c = ev->data;
    ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                   "kevent set event: %d: ft:%i fl:%04Xi",
                   c->fd, filter, flags);
    if (nchanges >= max_changes)
    {
        ngx_log_error(NGX_LOG_WARN, ev->log, 0,
                      "kqueue change list is filled up");
        ts.tv_sec = 0;
        ts.tv_nsec = 0;
        if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
                == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
            return NGX_ERROR;
        }
        nchanges = 0;
    }
    kev = &change_list[nchanges];
    kev->ident = c->fd;
    kev->filter = (short) filter;
    kev->flags = (u_short) flags;
    kev->udata = NGX_KQUEUE_UDATA_T((uintptr_t) ev | ev->instance);
    if (filter == EVFILT_VNODE)
    {
        kev->fflags = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND
                      | NOTE_ATTRIB | NOTE_RENAME
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
    || __FreeBSD_version >= 500018
                      | NOTE_REVOKE
#endif
                      ;
        kev->data = 0;
    }
    else
    {
#if (NGX_HAVE_LOWAT_EVENT)
        if (flags & NGX_LOWAT_EVENT)
        {
            kev->fflags = NOTE_LOWAT;
            kev->data = ev->available;
        }
        else
        {
            kev->fflags = 0;
            kev->data = 0;
        }
#else
        kev->fflags = 0;
        kev->data = 0;
#endif
    }
    ev->index = nchanges;
    nchanges++;
    if (flags & NGX_FLUSH_EVENT)
    {
        ts.tv_sec = 0;
        ts.tv_nsec = 0;
        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent flush");
        if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
                == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
            return NGX_ERROR;
        }
        nchanges = 0;
    }
    return NGX_OK;
}