1*3da8d17dSfengbojiang(姜凤波) 
2*3da8d17dSfengbojiang(姜凤波) /*
3*3da8d17dSfengbojiang(姜凤波)  * Copyright (C) Igor Sysoev
4*3da8d17dSfengbojiang(姜凤波)  * Copyright (C) Nginx, Inc.
5*3da8d17dSfengbojiang(姜凤波)  */
6*3da8d17dSfengbojiang(姜凤波) 
7*3da8d17dSfengbojiang(姜凤波) 
8*3da8d17dSfengbojiang(姜凤波) #include <ngx_config.h>
9*3da8d17dSfengbojiang(姜凤波) #include <ngx_core.h>
10*3da8d17dSfengbojiang(姜凤波) #include <ngx_event.h>
11*3da8d17dSfengbojiang(姜凤波) 
12*3da8d17dSfengbojiang(姜凤波) 
13*3da8d17dSfengbojiang(姜凤波) typedef struct {
14*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t  changes;
15*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t  events;
16*3da8d17dSfengbojiang(姜凤波) } ngx_kqueue_conf_t;
17*3da8d17dSfengbojiang(姜凤波) 
18*3da8d17dSfengbojiang(姜凤波) 
19*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer);
20*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
21*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_notify_init(ngx_log_t *log);
22*3da8d17dSfengbojiang(姜凤波) #endif
23*3da8d17dSfengbojiang(姜凤波) static void ngx_kqueue_done(ngx_cycle_t *cycle);
24*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event,
25*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
26*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event,
27*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
28*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter,
29*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
30*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
31*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_notify(ngx_event_handler_pt handler);
32*3da8d17dSfengbojiang(姜凤波) #endif
33*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
34*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
35*3da8d17dSfengbojiang(姜凤波) static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log,
36*3da8d17dSfengbojiang(姜凤波)     struct kevent *kev);
37*3da8d17dSfengbojiang(姜凤波) 
38*3da8d17dSfengbojiang(姜凤波) static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
39*3da8d17dSfengbojiang(姜凤波) static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf);
40*3da8d17dSfengbojiang(姜凤波) 
41*3da8d17dSfengbojiang(姜凤波) 
42*3da8d17dSfengbojiang(姜凤波) int                    ngx_kqueue = -1;
43*3da8d17dSfengbojiang(姜凤波) 
44*3da8d17dSfengbojiang(姜凤波) static struct kevent  *change_list;
45*3da8d17dSfengbojiang(姜凤波) static struct kevent  *event_list;
46*3da8d17dSfengbojiang(姜凤波) static ngx_uint_t      max_changes, nchanges, nevents;
47*3da8d17dSfengbojiang(姜凤波) 
48*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
49*3da8d17dSfengbojiang(姜凤波) static ngx_event_t     notify_event;
50*3da8d17dSfengbojiang(姜凤波) static struct kevent   notify_kev;
51*3da8d17dSfengbojiang(姜凤波) #endif
52*3da8d17dSfengbojiang(姜凤波) 
53*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_FSTACK)
54*3da8d17dSfengbojiang(姜凤波) extern int kqueue(void);
55*3da8d17dSfengbojiang(姜凤波) extern int kevent(int kq, const struct kevent *changelist, int nchanges,
56*3da8d17dSfengbojiang(姜凤波)     struct kevent *eventlist, int nevents, const struct timespec *timeout);
57*3da8d17dSfengbojiang(姜凤波) #endif
58*3da8d17dSfengbojiang(姜凤波) 
59*3da8d17dSfengbojiang(姜凤波) static ngx_str_t      kqueue_name = ngx_string("kqueue");
60*3da8d17dSfengbojiang(姜凤波) 
61*3da8d17dSfengbojiang(姜凤波) static ngx_command_t  ngx_kqueue_commands[] = {
62*3da8d17dSfengbojiang(姜凤波) 
63*3da8d17dSfengbojiang(姜凤波)     { ngx_string("kqueue_changes"),
64*3da8d17dSfengbojiang(姜凤波)       NGX_EVENT_CONF|NGX_CONF_TAKE1,
65*3da8d17dSfengbojiang(姜凤波)       ngx_conf_set_num_slot,
66*3da8d17dSfengbojiang(姜凤波)       0,
67*3da8d17dSfengbojiang(姜凤波)       offsetof(ngx_kqueue_conf_t, changes),
68*3da8d17dSfengbojiang(姜凤波)       NULL },
69*3da8d17dSfengbojiang(姜凤波) 
70*3da8d17dSfengbojiang(姜凤波)     { ngx_string("kqueue_events"),
71*3da8d17dSfengbojiang(姜凤波)       NGX_EVENT_CONF|NGX_CONF_TAKE1,
72*3da8d17dSfengbojiang(姜凤波)       ngx_conf_set_num_slot,
73*3da8d17dSfengbojiang(姜凤波)       0,
74*3da8d17dSfengbojiang(姜凤波)       offsetof(ngx_kqueue_conf_t, events),
75*3da8d17dSfengbojiang(姜凤波)       NULL },
76*3da8d17dSfengbojiang(姜凤波) 
77*3da8d17dSfengbojiang(姜凤波)       ngx_null_command
78*3da8d17dSfengbojiang(姜凤波) };
79*3da8d17dSfengbojiang(姜凤波) 
80*3da8d17dSfengbojiang(姜凤波) 
81*3da8d17dSfengbojiang(姜凤波) static ngx_event_module_t  ngx_kqueue_module_ctx = {
82*3da8d17dSfengbojiang(姜凤波)     &kqueue_name,
83*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_create_conf,                /* create configuration */
84*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_init_conf,                  /* init configuration */
85*3da8d17dSfengbojiang(姜凤波) 
86*3da8d17dSfengbojiang(姜凤波)     {
87*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_add_event,              /* add an event */
88*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_del_event,              /* delete an event */
89*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_add_event,              /* enable an event */
90*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_del_event,              /* disable an event */
91*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* add an connection */
92*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* delete an connection */
93*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
94*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_notify,                 /* trigger a notify */
95*3da8d17dSfengbojiang(姜凤波) #else
96*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* trigger a notify */
97*3da8d17dSfengbojiang(姜凤波) #endif
98*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_process_events,         /* process the events */
99*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_init,                   /* init the events */
100*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_done                    /* done the events */
101*3da8d17dSfengbojiang(姜凤波)     }
102*3da8d17dSfengbojiang(姜凤波) 
103*3da8d17dSfengbojiang(姜凤波) };
104*3da8d17dSfengbojiang(姜凤波) 
105*3da8d17dSfengbojiang(姜凤波) ngx_module_t  ngx_kqueue_module = {
106*3da8d17dSfengbojiang(姜凤波)     NGX_MODULE_V1,
107*3da8d17dSfengbojiang(姜凤波)     &ngx_kqueue_module_ctx,                /* module context */
108*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_commands,                   /* module directives */
109*3da8d17dSfengbojiang(姜凤波)     NGX_EVENT_MODULE,                      /* module type */
110*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init master */
111*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init module */
112*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init process */
113*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init thread */
114*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit thread */
115*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit process */
116*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit master */
117*3da8d17dSfengbojiang(姜凤波)     NGX_MODULE_V1_PADDING
118*3da8d17dSfengbojiang(姜凤波) };
119*3da8d17dSfengbojiang(姜凤波) 
120*3da8d17dSfengbojiang(姜凤波) 
121*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_init(ngx_cycle_t * cycle,ngx_msec_t timer)122*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
123*3da8d17dSfengbojiang(姜凤波) {
124*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_conf_t  *kcf;
125*3da8d17dSfengbojiang(姜凤波)     struct timespec     ts;
126*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_TIMER_EVENT)
127*3da8d17dSfengbojiang(姜凤波)     struct kevent       kev;
128*3da8d17dSfengbojiang(姜凤波) #endif
129*3da8d17dSfengbojiang(姜凤波) 
130*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_FSTACK)
131*3da8d17dSfengbojiang(姜凤波)     if(ngx_ff_process == NGX_FF_PROCESS_NONE) {
132*3da8d17dSfengbojiang(姜凤波)         return NGX_OK;
133*3da8d17dSfengbojiang(姜凤波)     }
134*3da8d17dSfengbojiang(姜凤波) #endif
135*3da8d17dSfengbojiang(姜凤波) 
136*3da8d17dSfengbojiang(姜凤波)     kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module);
137*3da8d17dSfengbojiang(姜凤波) 
138*3da8d17dSfengbojiang(姜凤波)     if (ngx_kqueue == -1) {
139*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue = kqueue();
140*3da8d17dSfengbojiang(姜凤波) 
141*3da8d17dSfengbojiang(姜凤波)         if (ngx_kqueue == -1) {
142*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
143*3da8d17dSfengbojiang(姜凤波)                           "kqueue() failed");
144*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
145*3da8d17dSfengbojiang(姜凤波)         }
146*3da8d17dSfengbojiang(姜凤波) 
147*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
148*3da8d17dSfengbojiang(姜凤波)         if (ngx_kqueue_notify_init(cycle->log) != NGX_OK) {
149*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
150*3da8d17dSfengbojiang(姜凤波)         }
151*3da8d17dSfengbojiang(姜凤波) #endif
152*3da8d17dSfengbojiang(姜凤波)     }
153*3da8d17dSfengbojiang(姜凤波) 
154*3da8d17dSfengbojiang(姜凤波)     if (max_changes < kcf->changes) {
155*3da8d17dSfengbojiang(姜凤波)         if (nchanges) {
156*3da8d17dSfengbojiang(姜凤波)             ts.tv_sec = 0;
157*3da8d17dSfengbojiang(姜凤波)             ts.tv_nsec = 0;
158*3da8d17dSfengbojiang(姜凤波) 
159*3da8d17dSfengbojiang(姜凤波)             if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
160*3da8d17dSfengbojiang(姜凤波)                 == -1)
161*3da8d17dSfengbojiang(姜凤波)             {
162*3da8d17dSfengbojiang(姜凤波)                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
163*3da8d17dSfengbojiang(姜凤波)                               "kevent() failed");
164*3da8d17dSfengbojiang(姜凤波)                 return NGX_ERROR;
165*3da8d17dSfengbojiang(姜凤波)             }
166*3da8d17dSfengbojiang(姜凤波)             nchanges = 0;
167*3da8d17dSfengbojiang(姜凤波)         }
168*3da8d17dSfengbojiang(姜凤波) 
169*3da8d17dSfengbojiang(姜凤波)         if (change_list) {
170*3da8d17dSfengbojiang(姜凤波)             ngx_free(change_list);
171*3da8d17dSfengbojiang(姜凤波)         }
172*3da8d17dSfengbojiang(姜凤波) 
173*3da8d17dSfengbojiang(姜凤波)         change_list = ngx_alloc(kcf->changes * sizeof(struct kevent),
174*3da8d17dSfengbojiang(姜凤波)                                 cycle->log);
175*3da8d17dSfengbojiang(姜凤波)         if (change_list == NULL) {
176*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
177*3da8d17dSfengbojiang(姜凤波)         }
178*3da8d17dSfengbojiang(姜凤波)     }
179*3da8d17dSfengbojiang(姜凤波) 
180*3da8d17dSfengbojiang(姜凤波)     max_changes = kcf->changes;
181*3da8d17dSfengbojiang(姜凤波) 
182*3da8d17dSfengbojiang(姜凤波)     if (nevents < kcf->events) {
183*3da8d17dSfengbojiang(姜凤波)         if (event_list) {
184*3da8d17dSfengbojiang(姜凤波)             ngx_free(event_list);
185*3da8d17dSfengbojiang(姜凤波)         }
186*3da8d17dSfengbojiang(姜凤波) 
187*3da8d17dSfengbojiang(姜凤波)         event_list = ngx_alloc(kcf->events * sizeof(struct kevent), cycle->log);
188*3da8d17dSfengbojiang(姜凤波)         if (event_list == NULL) {
189*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
190*3da8d17dSfengbojiang(姜凤波)         }
191*3da8d17dSfengbojiang(姜凤波)     }
192*3da8d17dSfengbojiang(姜凤波) 
193*3da8d17dSfengbojiang(姜凤波)     ngx_event_flags = NGX_USE_ONESHOT_EVENT
194*3da8d17dSfengbojiang(姜凤波)                       |NGX_USE_KQUEUE_EVENT
195*3da8d17dSfengbojiang(姜凤波)                       |NGX_USE_VNODE_EVENT;
196*3da8d17dSfengbojiang(姜凤波) 
197*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_TIMER_EVENT)
198*3da8d17dSfengbojiang(姜凤波) 
199*3da8d17dSfengbojiang(姜凤波)     if (timer) {
200*3da8d17dSfengbojiang(姜凤波)         kev.ident = 0;
201*3da8d17dSfengbojiang(姜凤波)         kev.filter = EVFILT_TIMER;
202*3da8d17dSfengbojiang(姜凤波)         kev.flags = EV_ADD|EV_ENABLE;
203*3da8d17dSfengbojiang(姜凤波)         kev.fflags = 0;
204*3da8d17dSfengbojiang(姜凤波)         kev.data = timer;
205*3da8d17dSfengbojiang(姜凤波)         kev.udata = 0;
206*3da8d17dSfengbojiang(姜凤波) 
207*3da8d17dSfengbojiang(姜凤波)         ts.tv_sec = 0;
208*3da8d17dSfengbojiang(姜凤波)         ts.tv_nsec = 0;
209*3da8d17dSfengbojiang(姜凤波) 
210*3da8d17dSfengbojiang(姜凤波)         if (kevent(ngx_kqueue, &kev, 1, NULL, 0, &ts) == -1) {
211*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
212*3da8d17dSfengbojiang(姜凤波)                           "kevent(EVFILT_TIMER) failed");
213*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
214*3da8d17dSfengbojiang(姜凤波)         }
215*3da8d17dSfengbojiang(姜凤波) 
216*3da8d17dSfengbojiang(姜凤波)         ngx_event_flags |= NGX_USE_TIMER_EVENT;
217*3da8d17dSfengbojiang(姜凤波)     }
218*3da8d17dSfengbojiang(姜凤波) 
219*3da8d17dSfengbojiang(姜凤波) #endif
220*3da8d17dSfengbojiang(姜凤波) 
221*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_CLEAR_EVENT)
222*3da8d17dSfengbojiang(姜凤波)     ngx_event_flags |= NGX_USE_CLEAR_EVENT;
223*3da8d17dSfengbojiang(姜凤波) #else
224*3da8d17dSfengbojiang(姜凤波)     ngx_event_flags |= NGX_USE_LEVEL_EVENT;
225*3da8d17dSfengbojiang(姜凤波) #endif
226*3da8d17dSfengbojiang(姜凤波) 
227*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_LOWAT_EVENT)
228*3da8d17dSfengbojiang(姜凤波)     ngx_event_flags |= NGX_USE_LOWAT_EVENT;
229*3da8d17dSfengbojiang(姜凤波) #endif
230*3da8d17dSfengbojiang(姜凤波) 
231*3da8d17dSfengbojiang(姜凤波)     nevents = kcf->events;
232*3da8d17dSfengbojiang(姜凤波) 
233*3da8d17dSfengbojiang(姜凤波)     ngx_io = ngx_os_io;
234*3da8d17dSfengbojiang(姜凤波) 
235*3da8d17dSfengbojiang(姜凤波)     ngx_event_actions = ngx_kqueue_module_ctx.actions;
236*3da8d17dSfengbojiang(姜凤波) 
237*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
238*3da8d17dSfengbojiang(姜凤波) }
239*3da8d17dSfengbojiang(姜凤波) 
240*3da8d17dSfengbojiang(姜凤波) 
241*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
242*3da8d17dSfengbojiang(姜凤波) 
243*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_notify_init(ngx_log_t * log)244*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_notify_init(ngx_log_t *log)
245*3da8d17dSfengbojiang(姜凤波) {
246*3da8d17dSfengbojiang(姜凤波)     notify_kev.ident = 0;
247*3da8d17dSfengbojiang(姜凤波)     notify_kev.filter = EVFILT_USER;
248*3da8d17dSfengbojiang(姜凤波)     notify_kev.data = 0;
249*3da8d17dSfengbojiang(姜凤波)     notify_kev.flags = EV_ADD|EV_CLEAR;
250*3da8d17dSfengbojiang(姜凤波)     notify_kev.fflags = 0;
251*3da8d17dSfengbojiang(姜凤波)     notify_kev.udata = 0;
252*3da8d17dSfengbojiang(姜凤波) 
253*3da8d17dSfengbojiang(姜凤波)     if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
254*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
255*3da8d17dSfengbojiang(姜凤波)                       "kevent(EVFILT_USER, EV_ADD) failed");
256*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
257*3da8d17dSfengbojiang(姜凤波)     }
258*3da8d17dSfengbojiang(姜凤波) 
259*3da8d17dSfengbojiang(姜凤波)     notify_event.active = 1;
260*3da8d17dSfengbojiang(姜凤波)     notify_event.log = log;
261*3da8d17dSfengbojiang(姜凤波) 
262*3da8d17dSfengbojiang(姜凤波)     notify_kev.flags = 0;
263*3da8d17dSfengbojiang(姜凤波)     notify_kev.fflags = NOTE_TRIGGER;
264*3da8d17dSfengbojiang(姜凤波)     notify_kev.udata = NGX_KQUEUE_UDATA_T ((uintptr_t) &notify_event);
265*3da8d17dSfengbojiang(姜凤波) 
266*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
267*3da8d17dSfengbojiang(姜凤波) }
268*3da8d17dSfengbojiang(姜凤波) 
269*3da8d17dSfengbojiang(姜凤波) #endif
270*3da8d17dSfengbojiang(姜凤波) 
271*3da8d17dSfengbojiang(姜凤波) 
272*3da8d17dSfengbojiang(姜凤波) static void
ngx_kqueue_done(ngx_cycle_t * cycle)273*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_done(ngx_cycle_t *cycle)
274*3da8d17dSfengbojiang(姜凤波) {
275*3da8d17dSfengbojiang(姜凤波)     if (close(ngx_kqueue) == -1) {
276*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
277*3da8d17dSfengbojiang(姜凤波)                       "kqueue close() failed");
278*3da8d17dSfengbojiang(姜凤波)     }
279*3da8d17dSfengbojiang(姜凤波) 
280*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue = -1;
281*3da8d17dSfengbojiang(姜凤波) 
282*3da8d17dSfengbojiang(姜凤波)     ngx_free(change_list);
283*3da8d17dSfengbojiang(姜凤波)     ngx_free(event_list);
284*3da8d17dSfengbojiang(姜凤波) 
285*3da8d17dSfengbojiang(姜凤波)     change_list = NULL;
286*3da8d17dSfengbojiang(姜凤波)     event_list = NULL;
287*3da8d17dSfengbojiang(姜凤波)     max_changes = 0;
288*3da8d17dSfengbojiang(姜凤波)     nchanges = 0;
289*3da8d17dSfengbojiang(姜凤波)     nevents = 0;
290*3da8d17dSfengbojiang(姜凤波) }
291*3da8d17dSfengbojiang(姜凤波) 
292*3da8d17dSfengbojiang(姜凤波) 
293*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_add_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)294*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
295*3da8d17dSfengbojiang(姜凤波) {
296*3da8d17dSfengbojiang(姜凤波)     ngx_int_t          rc;
297*3da8d17dSfengbojiang(姜凤波) #if 0
298*3da8d17dSfengbojiang(姜凤波)     ngx_event_t       *e;
299*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t  *c;
300*3da8d17dSfengbojiang(姜凤波) #endif
301*3da8d17dSfengbojiang(姜凤波) 
302*3da8d17dSfengbojiang(姜凤波)     ev->active = 1;
303*3da8d17dSfengbojiang(姜凤波)     ev->disabled = 0;
304*3da8d17dSfengbojiang(姜凤波)     ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0;
305*3da8d17dSfengbojiang(姜凤波) 
306*3da8d17dSfengbojiang(姜凤波) #if 0
307*3da8d17dSfengbojiang(姜凤波) 
308*3da8d17dSfengbojiang(姜凤波)     if (ev->index < nchanges
309*3da8d17dSfengbojiang(姜凤波)         && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
310*3da8d17dSfengbojiang(姜凤波)             == (uintptr_t) ev)
311*3da8d17dSfengbojiang(姜凤波)     {
312*3da8d17dSfengbojiang(姜凤波)         if (change_list[ev->index].flags == EV_DISABLE) {
313*3da8d17dSfengbojiang(姜凤波) 
314*3da8d17dSfengbojiang(姜凤波)             /*
315*3da8d17dSfengbojiang(姜凤波)              * if the EV_DISABLE is still not passed to a kernel
316*3da8d17dSfengbojiang(姜凤波)              * we will not pass it
317*3da8d17dSfengbojiang(姜凤波)              */
318*3da8d17dSfengbojiang(姜凤波) 
319*3da8d17dSfengbojiang(姜凤波)             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
320*3da8d17dSfengbojiang(姜凤波)                            "kevent activated: %d: ft:%i",
321*3da8d17dSfengbojiang(姜凤波)                            ngx_event_ident(ev->data), event);
322*3da8d17dSfengbojiang(姜凤波) 
323*3da8d17dSfengbojiang(姜凤波)             if (ev->index < --nchanges) {
324*3da8d17dSfengbojiang(姜凤波)                 e = (ngx_event_t *)
325*3da8d17dSfengbojiang(姜凤波)                     ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
326*3da8d17dSfengbojiang(姜凤波)                 change_list[ev->index] = change_list[nchanges];
327*3da8d17dSfengbojiang(姜凤波)                 e->index = ev->index;
328*3da8d17dSfengbojiang(姜凤波)             }
329*3da8d17dSfengbojiang(姜凤波) 
330*3da8d17dSfengbojiang(姜凤波)             return NGX_OK;
331*3da8d17dSfengbojiang(姜凤波)         }
332*3da8d17dSfengbojiang(姜凤波) 
333*3da8d17dSfengbojiang(姜凤波)         c = ev->data;
334*3da8d17dSfengbojiang(姜凤波) 
335*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
336*3da8d17dSfengbojiang(姜凤波)                       "previous event on #%d were not passed in kernel", c->fd);
337*3da8d17dSfengbojiang(姜凤波) 
338*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
339*3da8d17dSfengbojiang(姜凤波)     }
340*3da8d17dSfengbojiang(姜凤波) 
341*3da8d17dSfengbojiang(姜凤波) #endif
342*3da8d17dSfengbojiang(姜凤波) 
343*3da8d17dSfengbojiang(姜凤波)     rc = ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags);
344*3da8d17dSfengbojiang(姜凤波) 
345*3da8d17dSfengbojiang(姜凤波)     return rc;
346*3da8d17dSfengbojiang(姜凤波) }
347*3da8d17dSfengbojiang(姜凤波) 
348*3da8d17dSfengbojiang(姜凤波) 
349*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_del_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)350*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
351*3da8d17dSfengbojiang(姜凤波) {
352*3da8d17dSfengbojiang(姜凤波)     ngx_int_t     rc;
353*3da8d17dSfengbojiang(姜凤波)     ngx_event_t  *e;
354*3da8d17dSfengbojiang(姜凤波) 
355*3da8d17dSfengbojiang(姜凤波)     ev->active = 0;
356*3da8d17dSfengbojiang(姜凤波)     ev->disabled = 0;
357*3da8d17dSfengbojiang(姜凤波) 
358*3da8d17dSfengbojiang(姜凤波)     if (ev->index < nchanges
359*3da8d17dSfengbojiang(姜凤波)         && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
360*3da8d17dSfengbojiang(姜凤波)             == (uintptr_t) ev)
361*3da8d17dSfengbojiang(姜凤波)     {
362*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
363*3da8d17dSfengbojiang(姜凤波)                        "kevent deleted: %d: ft:%i",
364*3da8d17dSfengbojiang(姜凤波)                        ngx_event_ident(ev->data), event);
365*3da8d17dSfengbojiang(姜凤波) 
366*3da8d17dSfengbojiang(姜凤波)         /* if the event is still not passed to a kernel we will not pass it */
367*3da8d17dSfengbojiang(姜凤波) 
368*3da8d17dSfengbojiang(姜凤波)         nchanges--;
369*3da8d17dSfengbojiang(姜凤波) 
370*3da8d17dSfengbojiang(姜凤波)         if (ev->index < nchanges) {
371*3da8d17dSfengbojiang(姜凤波)             e = (ngx_event_t *)
372*3da8d17dSfengbojiang(姜凤波)                     ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
373*3da8d17dSfengbojiang(姜凤波)             change_list[ev->index] = change_list[nchanges];
374*3da8d17dSfengbojiang(姜凤波)             e->index = ev->index;
375*3da8d17dSfengbojiang(姜凤波)         }
376*3da8d17dSfengbojiang(姜凤波) 
377*3da8d17dSfengbojiang(姜凤波)         return NGX_OK;
378*3da8d17dSfengbojiang(姜凤波)     }
379*3da8d17dSfengbojiang(姜凤波) 
380*3da8d17dSfengbojiang(姜凤波)     /*
381*3da8d17dSfengbojiang(姜凤波)      * when the file descriptor is closed the kqueue automatically deletes
382*3da8d17dSfengbojiang(姜凤波)      * its filters so we do not need to delete explicitly the event
383*3da8d17dSfengbojiang(姜凤波)      * before the closing the file descriptor.
384*3da8d17dSfengbojiang(姜凤波)      */
385*3da8d17dSfengbojiang(姜凤波) 
386*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_CLOSE_EVENT) {
387*3da8d17dSfengbojiang(姜凤波)         return NGX_OK;
388*3da8d17dSfengbojiang(姜凤波)     }
389*3da8d17dSfengbojiang(姜凤波) 
390*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_DISABLE_EVENT) {
391*3da8d17dSfengbojiang(姜凤波)         ev->disabled = 1;
392*3da8d17dSfengbojiang(姜凤波) 
393*3da8d17dSfengbojiang(姜凤波)     } else {
394*3da8d17dSfengbojiang(姜凤波)         flags |= EV_DELETE;
395*3da8d17dSfengbojiang(姜凤波)     }
396*3da8d17dSfengbojiang(姜凤波) 
397*3da8d17dSfengbojiang(姜凤波)     rc = ngx_kqueue_set_event(ev, event, flags);
398*3da8d17dSfengbojiang(姜凤波) 
399*3da8d17dSfengbojiang(姜凤波)     return rc;
400*3da8d17dSfengbojiang(姜凤波) }
401*3da8d17dSfengbojiang(姜凤波) 
402*3da8d17dSfengbojiang(姜凤波) 
403*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_set_event(ngx_event_t * ev,ngx_int_t filter,ngx_uint_t flags)404*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
405*3da8d17dSfengbojiang(姜凤波) {
406*3da8d17dSfengbojiang(姜凤波)     struct kevent     *kev;
407*3da8d17dSfengbojiang(姜凤波)     struct timespec    ts;
408*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t  *c;
409*3da8d17dSfengbojiang(姜凤波) 
410*3da8d17dSfengbojiang(姜凤波)     c = ev->data;
411*3da8d17dSfengbojiang(姜凤波) 
412*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
413*3da8d17dSfengbojiang(姜凤波)                    "kevent set event: %d: ft:%i fl:%04Xi",
414*3da8d17dSfengbojiang(姜凤波)                    c->fd, filter, flags);
415*3da8d17dSfengbojiang(姜凤波) 
416*3da8d17dSfengbojiang(姜凤波)     if (nchanges >= max_changes) {
417*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_WARN, ev->log, 0,
418*3da8d17dSfengbojiang(姜凤波)                       "kqueue change list is filled up");
419*3da8d17dSfengbojiang(姜凤波) 
420*3da8d17dSfengbojiang(姜凤波)         ts.tv_sec = 0;
421*3da8d17dSfengbojiang(姜凤波)         ts.tv_nsec = 0;
422*3da8d17dSfengbojiang(姜凤波) 
423*3da8d17dSfengbojiang(姜凤波)         if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
424*3da8d17dSfengbojiang(姜凤波)             == -1)
425*3da8d17dSfengbojiang(姜凤波)         {
426*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
427*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
428*3da8d17dSfengbojiang(姜凤波)         }
429*3da8d17dSfengbojiang(姜凤波) 
430*3da8d17dSfengbojiang(姜凤波)         nchanges = 0;
431*3da8d17dSfengbojiang(姜凤波)     }
432*3da8d17dSfengbojiang(姜凤波) 
433*3da8d17dSfengbojiang(姜凤波)     kev = &change_list[nchanges];
434*3da8d17dSfengbojiang(姜凤波) 
435*3da8d17dSfengbojiang(姜凤波)     kev->ident = c->fd;
436*3da8d17dSfengbojiang(姜凤波)     kev->filter = (short) filter;
437*3da8d17dSfengbojiang(姜凤波)     kev->flags = (u_short) flags;
438*3da8d17dSfengbojiang(姜凤波)     kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
439*3da8d17dSfengbojiang(姜凤波) 
440*3da8d17dSfengbojiang(姜凤波)     if (filter == EVFILT_VNODE) {
441*3da8d17dSfengbojiang(姜凤波)         kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
442*3da8d17dSfengbojiang(姜凤波)                                  |NOTE_ATTRIB|NOTE_RENAME
443*3da8d17dSfengbojiang(姜凤波) #if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
444*3da8d17dSfengbojiang(姜凤波)     || __FreeBSD_version >= 500018
445*3da8d17dSfengbojiang(姜凤波)                                  |NOTE_REVOKE
446*3da8d17dSfengbojiang(姜凤波) #endif
447*3da8d17dSfengbojiang(姜凤波)                       ;
448*3da8d17dSfengbojiang(姜凤波)         kev->data = 0;
449*3da8d17dSfengbojiang(姜凤波) 
450*3da8d17dSfengbojiang(姜凤波)     } else {
451*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_LOWAT_EVENT)
452*3da8d17dSfengbojiang(姜凤波)         if (flags & NGX_LOWAT_EVENT) {
453*3da8d17dSfengbojiang(姜凤波)             kev->fflags = NOTE_LOWAT;
454*3da8d17dSfengbojiang(姜凤波)             kev->data = ev->available;
455*3da8d17dSfengbojiang(姜凤波) 
456*3da8d17dSfengbojiang(姜凤波)         } else {
457*3da8d17dSfengbojiang(姜凤波)             kev->fflags = 0;
458*3da8d17dSfengbojiang(姜凤波)             kev->data = 0;
459*3da8d17dSfengbojiang(姜凤波)         }
460*3da8d17dSfengbojiang(姜凤波) #else
461*3da8d17dSfengbojiang(姜凤波)         kev->fflags = 0;
462*3da8d17dSfengbojiang(姜凤波)         kev->data = 0;
463*3da8d17dSfengbojiang(姜凤波) #endif
464*3da8d17dSfengbojiang(姜凤波)     }
465*3da8d17dSfengbojiang(姜凤波) 
466*3da8d17dSfengbojiang(姜凤波)     ev->index = nchanges;
467*3da8d17dSfengbojiang(姜凤波)     nchanges++;
468*3da8d17dSfengbojiang(姜凤波) 
469*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_FLUSH_EVENT) {
470*3da8d17dSfengbojiang(姜凤波)         ts.tv_sec = 0;
471*3da8d17dSfengbojiang(姜凤波)         ts.tv_nsec = 0;
472*3da8d17dSfengbojiang(姜凤波) 
473*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent flush");
474*3da8d17dSfengbojiang(姜凤波) 
475*3da8d17dSfengbojiang(姜凤波)         if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
476*3da8d17dSfengbojiang(姜凤波)             == -1)
477*3da8d17dSfengbojiang(姜凤波)         {
478*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
479*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
480*3da8d17dSfengbojiang(姜凤波)         }
481*3da8d17dSfengbojiang(姜凤波) 
482*3da8d17dSfengbojiang(姜凤波)         nchanges = 0;
483*3da8d17dSfengbojiang(姜凤波)     }
484*3da8d17dSfengbojiang(姜凤波) 
485*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
486*3da8d17dSfengbojiang(姜凤波) }
487*3da8d17dSfengbojiang(姜凤波) 
488*3da8d17dSfengbojiang(姜凤波) 
489*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
490*3da8d17dSfengbojiang(姜凤波) 
491*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_notify(ngx_event_handler_pt handler)492*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_notify(ngx_event_handler_pt handler)
493*3da8d17dSfengbojiang(姜凤波) {
494*3da8d17dSfengbojiang(姜凤波)     notify_event.handler = handler;
495*3da8d17dSfengbojiang(姜凤波) 
496*3da8d17dSfengbojiang(姜凤波)     if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
497*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, notify_event.log, ngx_errno,
498*3da8d17dSfengbojiang(姜凤波)                       "kevent(EVFILT_USER, NOTE_TRIGGER) failed");
499*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
500*3da8d17dSfengbojiang(姜凤波)     }
501*3da8d17dSfengbojiang(姜凤波) 
502*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
503*3da8d17dSfengbojiang(姜凤波) }
504*3da8d17dSfengbojiang(姜凤波) 
505*3da8d17dSfengbojiang(姜凤波) #endif
506*3da8d17dSfengbojiang(姜凤波) 
507*3da8d17dSfengbojiang(姜凤波) 
508*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_kqueue_process_events(ngx_cycle_t * cycle,ngx_msec_t timer,ngx_uint_t flags)509*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
510*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags)
511*3da8d17dSfengbojiang(姜凤波) {
512*3da8d17dSfengbojiang(姜凤波)     int               events, n;
513*3da8d17dSfengbojiang(姜凤波)     ngx_int_t         i, instance;
514*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t        level;
515*3da8d17dSfengbojiang(姜凤波)     ngx_err_t         err;
516*3da8d17dSfengbojiang(姜凤波)     ngx_event_t      *ev;
517*3da8d17dSfengbojiang(姜凤波)     ngx_queue_t      *queue;
518*3da8d17dSfengbojiang(姜凤波)     struct timespec   ts, *tp;
519*3da8d17dSfengbojiang(姜凤波) 
520*3da8d17dSfengbojiang(姜凤波)     n = (int) nchanges;
521*3da8d17dSfengbojiang(姜凤波)     nchanges = 0;
522*3da8d17dSfengbojiang(姜凤波) 
523*3da8d17dSfengbojiang(姜凤波)     if (timer == NGX_TIMER_INFINITE) {
524*3da8d17dSfengbojiang(姜凤波)         tp = NULL;
525*3da8d17dSfengbojiang(姜凤波) 
526*3da8d17dSfengbojiang(姜凤波)     } else {
527*3da8d17dSfengbojiang(姜凤波) 
528*3da8d17dSfengbojiang(姜凤波)         ts.tv_sec = timer / 1000;
529*3da8d17dSfengbojiang(姜凤波)         ts.tv_nsec = (timer % 1000) * 1000000;
530*3da8d17dSfengbojiang(姜凤波) 
531*3da8d17dSfengbojiang(姜凤波)         /*
532*3da8d17dSfengbojiang(姜凤波)          * 64-bit Darwin kernel has the bug: kernel level ts.tv_nsec is
533*3da8d17dSfengbojiang(姜凤波)          * the int32_t while user level ts.tv_nsec is the long (64-bit),
534*3da8d17dSfengbojiang(姜凤波)          * so on the big endian PowerPC all nanoseconds are lost.
535*3da8d17dSfengbojiang(姜凤波)          */
536*3da8d17dSfengbojiang(姜凤波) 
537*3da8d17dSfengbojiang(姜凤波) #if (NGX_DARWIN_KEVENT_BUG)
538*3da8d17dSfengbojiang(姜凤波)         ts.tv_nsec <<= 32;
539*3da8d17dSfengbojiang(姜凤波) #endif
540*3da8d17dSfengbojiang(姜凤波) 
541*3da8d17dSfengbojiang(姜凤波)         tp = &ts;
542*3da8d17dSfengbojiang(姜凤波)     }
543*3da8d17dSfengbojiang(姜凤波) 
544*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_FSTACK)
545*3da8d17dSfengbojiang(姜凤波)     if (n > 0) {
546*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
547*3da8d17dSfengbojiang(姜凤波)                    "kevent timer: %M, changes: %d", timer, n);
548*3da8d17dSfengbojiang(姜凤波)     }
549*3da8d17dSfengbojiang(姜凤波) #else
550*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
551*3da8d17dSfengbojiang(姜凤波)                    "kevent timer: %M, changes: %d", timer, n);
552*3da8d17dSfengbojiang(姜凤波) #endif
553*3da8d17dSfengbojiang(姜凤波) 
554*3da8d17dSfengbojiang(姜凤波)     events = kevent(ngx_kqueue, change_list, n, event_list, (int) nevents, tp);
555*3da8d17dSfengbojiang(姜凤波) 
556*3da8d17dSfengbojiang(姜凤波)     err = (events == -1) ? ngx_errno : 0;
557*3da8d17dSfengbojiang(姜凤波) 
558*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
559*3da8d17dSfengbojiang(姜凤波)         ngx_time_update();
560*3da8d17dSfengbojiang(姜凤波)     }
561*3da8d17dSfengbojiang(姜凤波) 
562*3da8d17dSfengbojiang(姜凤波) #if !(NGX_HAVE_FSTACK)
563*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
564*3da8d17dSfengbojiang(姜凤波)                    "kevent events: %d", events);
565*3da8d17dSfengbojiang(姜凤波) #endif
566*3da8d17dSfengbojiang(姜凤波) 
567*3da8d17dSfengbojiang(姜凤波)     if (err) {
568*3da8d17dSfengbojiang(姜凤波)         if (err == NGX_EINTR) {
569*3da8d17dSfengbojiang(姜凤波) 
570*3da8d17dSfengbojiang(姜凤波)             if (ngx_event_timer_alarm) {
571*3da8d17dSfengbojiang(姜凤波)                 ngx_event_timer_alarm = 0;
572*3da8d17dSfengbojiang(姜凤波)                 return NGX_OK;
573*3da8d17dSfengbojiang(姜凤波)             }
574*3da8d17dSfengbojiang(姜凤波) 
575*3da8d17dSfengbojiang(姜凤波)             level = NGX_LOG_INFO;
576*3da8d17dSfengbojiang(姜凤波) 
577*3da8d17dSfengbojiang(姜凤波)         } else {
578*3da8d17dSfengbojiang(姜凤波)             level = NGX_LOG_ALERT;
579*3da8d17dSfengbojiang(姜凤波)         }
580*3da8d17dSfengbojiang(姜凤波) 
581*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(level, cycle->log, err, "kevent() failed");
582*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
583*3da8d17dSfengbojiang(姜凤波)     }
584*3da8d17dSfengbojiang(姜凤波) 
585*3da8d17dSfengbojiang(姜凤波)     if (events == 0) {
586*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_FSTACK)
587*3da8d17dSfengbojiang(姜凤波)         return NGX_OK;
588*3da8d17dSfengbojiang(姜凤波) #else
589*3da8d17dSfengbojiang(姜凤波)         if (timer != NGX_TIMER_INFINITE) {
590*3da8d17dSfengbojiang(姜凤波)             return NGX_OK;
591*3da8d17dSfengbojiang(姜凤波)         }
592*3da8d17dSfengbojiang(姜凤波) 
593*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
594*3da8d17dSfengbojiang(姜凤波)                       "kevent() returned no events without timeout");
595*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
596*3da8d17dSfengbojiang(姜凤波) #endif
597*3da8d17dSfengbojiang(姜凤波)     }
598*3da8d17dSfengbojiang(姜凤波) 
599*3da8d17dSfengbojiang(姜凤波)     for (i = 0; i < events; i++) {
600*3da8d17dSfengbojiang(姜凤波) 
601*3da8d17dSfengbojiang(姜凤波)         ngx_kqueue_dump_event(cycle->log, &event_list[i]);
602*3da8d17dSfengbojiang(姜凤波) 
603*3da8d17dSfengbojiang(姜凤波)         if (event_list[i].flags & EV_ERROR) {
604*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data,
605*3da8d17dSfengbojiang(姜凤波)                           "kevent() error on %d filter:%d flags:%04Xd",
606*3da8d17dSfengbojiang(姜凤波)                           (int) event_list[i].ident, event_list[i].filter,
607*3da8d17dSfengbojiang(姜凤波)                           event_list[i].flags);
608*3da8d17dSfengbojiang(姜凤波)             continue;
609*3da8d17dSfengbojiang(姜凤波)         }
610*3da8d17dSfengbojiang(姜凤波) 
611*3da8d17dSfengbojiang(姜凤波) #if (NGX_HAVE_TIMER_EVENT)
612*3da8d17dSfengbojiang(姜凤波) 
613*3da8d17dSfengbojiang(姜凤波)         if (event_list[i].filter == EVFILT_TIMER) {
614*3da8d17dSfengbojiang(姜凤波)             ngx_time_update();
615*3da8d17dSfengbojiang(姜凤波)             continue;
616*3da8d17dSfengbojiang(姜凤波)         }
617*3da8d17dSfengbojiang(姜凤波) 
618*3da8d17dSfengbojiang(姜凤波) #endif
619*3da8d17dSfengbojiang(姜凤波) 
620*3da8d17dSfengbojiang(姜凤波)         ev = (ngx_event_t *) event_list[i].udata;
621*3da8d17dSfengbojiang(姜凤波) 
622*3da8d17dSfengbojiang(姜凤波)         switch (event_list[i].filter) {
623*3da8d17dSfengbojiang(姜凤波) 
624*3da8d17dSfengbojiang(姜凤波)         case EVFILT_READ:
625*3da8d17dSfengbojiang(姜凤波)         case EVFILT_WRITE:
626*3da8d17dSfengbojiang(姜凤波) 
627*3da8d17dSfengbojiang(姜凤波)             instance = (uintptr_t) ev & 1;
628*3da8d17dSfengbojiang(姜凤波)             ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
629*3da8d17dSfengbojiang(姜凤波) 
630*3da8d17dSfengbojiang(姜凤波)             if (ev->closed || ev->instance != instance) {
631*3da8d17dSfengbojiang(姜凤波) 
632*3da8d17dSfengbojiang(姜凤波)                 /*
633*3da8d17dSfengbojiang(姜凤波)                  * the stale event from a file descriptor
634*3da8d17dSfengbojiang(姜凤波)                  * that was just closed in this iteration
635*3da8d17dSfengbojiang(姜凤波)                  */
636*3da8d17dSfengbojiang(姜凤波) 
637*3da8d17dSfengbojiang(姜凤波)                 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
638*3da8d17dSfengbojiang(姜凤波)                                "kevent: stale event %p", ev);
639*3da8d17dSfengbojiang(姜凤波)                 continue;
640*3da8d17dSfengbojiang(姜凤波)             }
641*3da8d17dSfengbojiang(姜凤波) 
642*3da8d17dSfengbojiang(姜凤波)             if (ev->log && (ev->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
643*3da8d17dSfengbojiang(姜凤波)                 ngx_kqueue_dump_event(ev->log, &event_list[i]);
644*3da8d17dSfengbojiang(姜凤波)             }
645*3da8d17dSfengbojiang(姜凤波) 
646*3da8d17dSfengbojiang(姜凤波)             if (ev->oneshot) {
647*3da8d17dSfengbojiang(姜凤波)                 ev->active = 0;
648*3da8d17dSfengbojiang(姜凤波)             }
649*3da8d17dSfengbojiang(姜凤波) 
650*3da8d17dSfengbojiang(姜凤波)             ev->available = event_list[i].data;
651*3da8d17dSfengbojiang(姜凤波) 
652*3da8d17dSfengbojiang(姜凤波)             if (event_list[i].flags & EV_EOF) {
653*3da8d17dSfengbojiang(姜凤波)                 ev->pending_eof = 1;
654*3da8d17dSfengbojiang(姜凤波)                 ev->kq_errno = event_list[i].fflags;
655*3da8d17dSfengbojiang(姜凤波)             }
656*3da8d17dSfengbojiang(姜凤波) 
657*3da8d17dSfengbojiang(姜凤波)             ev->ready = 1;
658*3da8d17dSfengbojiang(姜凤波) 
659*3da8d17dSfengbojiang(姜凤波)             break;
660*3da8d17dSfengbojiang(姜凤波) 
661*3da8d17dSfengbojiang(姜凤波)         case EVFILT_VNODE:
662*3da8d17dSfengbojiang(姜凤波)             ev->kq_vnode = 1;
663*3da8d17dSfengbojiang(姜凤波) 
664*3da8d17dSfengbojiang(姜凤波)             break;
665*3da8d17dSfengbojiang(姜凤波) 
666*3da8d17dSfengbojiang(姜凤波)         case EVFILT_AIO:
667*3da8d17dSfengbojiang(姜凤波)             ev->complete = 1;
668*3da8d17dSfengbojiang(姜凤波)             ev->ready = 1;
669*3da8d17dSfengbojiang(姜凤波) 
670*3da8d17dSfengbojiang(姜凤波)             break;
671*3da8d17dSfengbojiang(姜凤波) 
672*3da8d17dSfengbojiang(姜凤波) #ifdef EVFILT_USER
673*3da8d17dSfengbojiang(姜凤波)         case EVFILT_USER:
674*3da8d17dSfengbojiang(姜凤波)             break;
675*3da8d17dSfengbojiang(姜凤波) #endif
676*3da8d17dSfengbojiang(姜凤波) 
677*3da8d17dSfengbojiang(姜凤波)         default:
678*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
679*3da8d17dSfengbojiang(姜凤波)                           "unexpected kevent() filter %d",
680*3da8d17dSfengbojiang(姜凤波)                           event_list[i].filter);
681*3da8d17dSfengbojiang(姜凤波)             continue;
682*3da8d17dSfengbojiang(姜凤波)         }
683*3da8d17dSfengbojiang(姜凤波) 
684*3da8d17dSfengbojiang(姜凤波)         if (flags & NGX_POST_EVENTS) {
685*3da8d17dSfengbojiang(姜凤波)             queue = ev->accept ? &ngx_posted_accept_events
686*3da8d17dSfengbojiang(姜凤波)                                : &ngx_posted_events;
687*3da8d17dSfengbojiang(姜凤波) 
688*3da8d17dSfengbojiang(姜凤波)             ngx_post_event(ev, queue);
689*3da8d17dSfengbojiang(姜凤波) 
690*3da8d17dSfengbojiang(姜凤波)             continue;
691*3da8d17dSfengbojiang(姜凤波)         }
692*3da8d17dSfengbojiang(姜凤波) 
693*3da8d17dSfengbojiang(姜凤波)         ev->handler(ev);
694*3da8d17dSfengbojiang(姜凤波)     }
695*3da8d17dSfengbojiang(姜凤波) 
696*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
697*3da8d17dSfengbojiang(姜凤波) }
698*3da8d17dSfengbojiang(姜凤波) 
699*3da8d17dSfengbojiang(姜凤波) 
700*3da8d17dSfengbojiang(姜凤波) static ngx_inline void
ngx_kqueue_dump_event(ngx_log_t * log,struct kevent * kev)701*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_dump_event(ngx_log_t *log, struct kevent *kev)
702*3da8d17dSfengbojiang(姜凤波) {
703*3da8d17dSfengbojiang(姜凤波)     if (kev->ident > 0x8000000 && kev->ident != (unsigned) -1) {
704*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0,
705*3da8d17dSfengbojiang(姜凤波)                        "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p",
706*3da8d17dSfengbojiang(姜凤波)                        (void *) kev->ident, kev->filter,
707*3da8d17dSfengbojiang(姜凤波)                        kev->flags, kev->fflags,
708*3da8d17dSfengbojiang(姜凤波)                        (int) kev->data, kev->udata);
709*3da8d17dSfengbojiang(姜凤波) 
710*3da8d17dSfengbojiang(姜凤波)     } else {
711*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0,
712*3da8d17dSfengbojiang(姜凤波)                        "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p",
713*3da8d17dSfengbojiang(姜凤波)                        (int) kev->ident, kev->filter,
714*3da8d17dSfengbojiang(姜凤波)                        kev->flags, kev->fflags,
715*3da8d17dSfengbojiang(姜凤波)                        (int) kev->data, kev->udata);
716*3da8d17dSfengbojiang(姜凤波)     }
717*3da8d17dSfengbojiang(姜凤波) }
718*3da8d17dSfengbojiang(姜凤波) 
719*3da8d17dSfengbojiang(姜凤波) 
720*3da8d17dSfengbojiang(姜凤波) static void *
ngx_kqueue_create_conf(ngx_cycle_t * cycle)721*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_create_conf(ngx_cycle_t *cycle)
722*3da8d17dSfengbojiang(姜凤波) {
723*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_conf_t  *kcf;
724*3da8d17dSfengbojiang(姜凤波) 
725*3da8d17dSfengbojiang(姜凤波)     kcf = ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t));
726*3da8d17dSfengbojiang(姜凤波)     if (kcf == NULL) {
727*3da8d17dSfengbojiang(姜凤波)         return NULL;
728*3da8d17dSfengbojiang(姜凤波)     }
729*3da8d17dSfengbojiang(姜凤波) 
730*3da8d17dSfengbojiang(姜凤波)     kcf->changes = NGX_CONF_UNSET;
731*3da8d17dSfengbojiang(姜凤波)     kcf->events = NGX_CONF_UNSET;
732*3da8d17dSfengbojiang(姜凤波) 
733*3da8d17dSfengbojiang(姜凤波)     return kcf;
734*3da8d17dSfengbojiang(姜凤波) }
735*3da8d17dSfengbojiang(姜凤波) 
736*3da8d17dSfengbojiang(姜凤波) 
737*3da8d17dSfengbojiang(姜凤波) static char *
ngx_kqueue_init_conf(ngx_cycle_t * cycle,void * conf)738*3da8d17dSfengbojiang(姜凤波) ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
739*3da8d17dSfengbojiang(姜凤波) {
740*3da8d17dSfengbojiang(姜凤波)     ngx_kqueue_conf_t *kcf = conf;
741*3da8d17dSfengbojiang(姜凤波) 
742*3da8d17dSfengbojiang(姜凤波)     ngx_conf_init_uint_value(kcf->changes, 512);
743*3da8d17dSfengbojiang(姜凤波)     ngx_conf_init_uint_value(kcf->events, 512);
744*3da8d17dSfengbojiang(姜凤波) 
745*3da8d17dSfengbojiang(姜凤波)     return NGX_CONF_OK;
746*3da8d17dSfengbojiang(姜凤波) }
747