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(姜凤波) #if (NGX_TEST_BUILD_DEVPOLL)
14*3da8d17dSfengbojiang(姜凤波) 
15*3da8d17dSfengbojiang(姜凤波) /* Solaris declarations */
16*3da8d17dSfengbojiang(姜凤波) 
17*3da8d17dSfengbojiang(姜凤波) #ifndef POLLREMOVE
18*3da8d17dSfengbojiang(姜凤波) #define POLLREMOVE   0x0800
19*3da8d17dSfengbojiang(姜凤波) #endif
20*3da8d17dSfengbojiang(姜凤波) #define DP_POLL      0xD001
21*3da8d17dSfengbojiang(姜凤波) #define DP_ISPOLLED  0xD002
22*3da8d17dSfengbojiang(姜凤波) 
23*3da8d17dSfengbojiang(姜凤波) struct dvpoll {
24*3da8d17dSfengbojiang(姜凤波)     struct pollfd  *dp_fds;
25*3da8d17dSfengbojiang(姜凤波)     int             dp_nfds;
26*3da8d17dSfengbojiang(姜凤波)     int             dp_timeout;
27*3da8d17dSfengbojiang(姜凤波) };
28*3da8d17dSfengbojiang(姜凤波) 
29*3da8d17dSfengbojiang(姜凤波) #endif
30*3da8d17dSfengbojiang(姜凤波) 
31*3da8d17dSfengbojiang(姜凤波) 
32*3da8d17dSfengbojiang(姜凤波) typedef struct {
33*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t      changes;
34*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t      events;
35*3da8d17dSfengbojiang(姜凤波) } ngx_devpoll_conf_t;
36*3da8d17dSfengbojiang(姜凤波) 
37*3da8d17dSfengbojiang(姜凤波) 
38*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
39*3da8d17dSfengbojiang(姜凤波) static void ngx_devpoll_done(ngx_cycle_t *cycle);
40*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event,
41*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
42*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event,
43*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
44*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event,
45*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags);
46*3da8d17dSfengbojiang(姜凤波) static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle,
47*3da8d17dSfengbojiang(姜凤波)     ngx_msec_t timer, ngx_uint_t flags);
48*3da8d17dSfengbojiang(姜凤波) 
49*3da8d17dSfengbojiang(姜凤波) static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle);
50*3da8d17dSfengbojiang(姜凤波) static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf);
51*3da8d17dSfengbojiang(姜凤波) 
52*3da8d17dSfengbojiang(姜凤波) static int              dp = -1;
53*3da8d17dSfengbojiang(姜凤波) static struct pollfd   *change_list, *event_list;
54*3da8d17dSfengbojiang(姜凤波) static ngx_uint_t       nchanges, max_changes, nevents;
55*3da8d17dSfengbojiang(姜凤波) 
56*3da8d17dSfengbojiang(姜凤波) static ngx_event_t    **change_index;
57*3da8d17dSfengbojiang(姜凤波) 
58*3da8d17dSfengbojiang(姜凤波) 
59*3da8d17dSfengbojiang(姜凤波) static ngx_str_t      devpoll_name = ngx_string("/dev/poll");
60*3da8d17dSfengbojiang(姜凤波) 
61*3da8d17dSfengbojiang(姜凤波) static ngx_command_t  ngx_devpoll_commands[] = {
62*3da8d17dSfengbojiang(姜凤波) 
63*3da8d17dSfengbojiang(姜凤波)     { ngx_string("devpoll_changes"),
64*3da8d17dSfengbojiang(姜凤波)       NGX_EVENT_CONF|NGX_CONF_TAKE1,
65*3da8d17dSfengbojiang(姜凤波)       ngx_conf_set_num_slot,
66*3da8d17dSfengbojiang(姜凤波)       0,
67*3da8d17dSfengbojiang(姜凤波)       offsetof(ngx_devpoll_conf_t, changes),
68*3da8d17dSfengbojiang(姜凤波)       NULL },
69*3da8d17dSfengbojiang(姜凤波) 
70*3da8d17dSfengbojiang(姜凤波)     { ngx_string("devpoll_events"),
71*3da8d17dSfengbojiang(姜凤波)       NGX_EVENT_CONF|NGX_CONF_TAKE1,
72*3da8d17dSfengbojiang(姜凤波)       ngx_conf_set_num_slot,
73*3da8d17dSfengbojiang(姜凤波)       0,
74*3da8d17dSfengbojiang(姜凤波)       offsetof(ngx_devpoll_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_devpoll_module_ctx = {
82*3da8d17dSfengbojiang(姜凤波)     &devpoll_name,
83*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_create_conf,               /* create configuration */
84*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_init_conf,                 /* init configuration */
85*3da8d17dSfengbojiang(姜凤波) 
86*3da8d17dSfengbojiang(姜凤波)     {
87*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_add_event,             /* add an event */
88*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_del_event,             /* delete an event */
89*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_add_event,             /* enable an event */
90*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_del_event,             /* disable an event */
91*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* add an connection */
92*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* delete an connection */
93*3da8d17dSfengbojiang(姜凤波)         NULL,                              /* trigger a notify */
94*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_process_events,        /* process the events */
95*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_init,                  /* init the events */
96*3da8d17dSfengbojiang(姜凤波)         ngx_devpoll_done,                  /* done the events */
97*3da8d17dSfengbojiang(姜凤波)     }
98*3da8d17dSfengbojiang(姜凤波) 
99*3da8d17dSfengbojiang(姜凤波) };
100*3da8d17dSfengbojiang(姜凤波) 
101*3da8d17dSfengbojiang(姜凤波) ngx_module_t  ngx_devpoll_module = {
102*3da8d17dSfengbojiang(姜凤波)     NGX_MODULE_V1,
103*3da8d17dSfengbojiang(姜凤波)     &ngx_devpoll_module_ctx,               /* module context */
104*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_commands,                  /* module directives */
105*3da8d17dSfengbojiang(姜凤波)     NGX_EVENT_MODULE,                      /* module type */
106*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init master */
107*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init module */
108*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init process */
109*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* init thread */
110*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit thread */
111*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit process */
112*3da8d17dSfengbojiang(姜凤波)     NULL,                                  /* exit master */
113*3da8d17dSfengbojiang(姜凤波)     NGX_MODULE_V1_PADDING
114*3da8d17dSfengbojiang(姜凤波) };
115*3da8d17dSfengbojiang(姜凤波) 
116*3da8d17dSfengbojiang(姜凤波) 
117*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_devpoll_init(ngx_cycle_t * cycle,ngx_msec_t timer)118*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
119*3da8d17dSfengbojiang(姜凤波) {
120*3da8d17dSfengbojiang(姜凤波)     size_t               n;
121*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_conf_t  *dpcf;
122*3da8d17dSfengbojiang(姜凤波) 
123*3da8d17dSfengbojiang(姜凤波)     dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module);
124*3da8d17dSfengbojiang(姜凤波) 
125*3da8d17dSfengbojiang(姜凤波)     if (dp == -1) {
126*3da8d17dSfengbojiang(姜凤波)         dp = open("/dev/poll", O_RDWR);
127*3da8d17dSfengbojiang(姜凤波) 
128*3da8d17dSfengbojiang(姜凤波)         if (dp == -1) {
129*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
130*3da8d17dSfengbojiang(姜凤波)                           "open(/dev/poll) failed");
131*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
132*3da8d17dSfengbojiang(姜凤波)         }
133*3da8d17dSfengbojiang(姜凤波)     }
134*3da8d17dSfengbojiang(姜凤波) 
135*3da8d17dSfengbojiang(姜凤波)     if (max_changes < dpcf->changes) {
136*3da8d17dSfengbojiang(姜凤波)         if (nchanges) {
137*3da8d17dSfengbojiang(姜凤波)             n = nchanges * sizeof(struct pollfd);
138*3da8d17dSfengbojiang(姜凤波)             if (write(dp, change_list, n) != (ssize_t) n) {
139*3da8d17dSfengbojiang(姜凤波)                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
140*3da8d17dSfengbojiang(姜凤波)                               "write(/dev/poll) failed");
141*3da8d17dSfengbojiang(姜凤波)                 return NGX_ERROR;
142*3da8d17dSfengbojiang(姜凤波)             }
143*3da8d17dSfengbojiang(姜凤波) 
144*3da8d17dSfengbojiang(姜凤波)             nchanges = 0;
145*3da8d17dSfengbojiang(姜凤波)         }
146*3da8d17dSfengbojiang(姜凤波) 
147*3da8d17dSfengbojiang(姜凤波)         if (change_list) {
148*3da8d17dSfengbojiang(姜凤波)             ngx_free(change_list);
149*3da8d17dSfengbojiang(姜凤波)         }
150*3da8d17dSfengbojiang(姜凤波) 
151*3da8d17dSfengbojiang(姜凤波)         change_list = ngx_alloc(sizeof(struct pollfd) * dpcf->changes,
152*3da8d17dSfengbojiang(姜凤波)                                 cycle->log);
153*3da8d17dSfengbojiang(姜凤波)         if (change_list == NULL) {
154*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
155*3da8d17dSfengbojiang(姜凤波)         }
156*3da8d17dSfengbojiang(姜凤波) 
157*3da8d17dSfengbojiang(姜凤波)         if (change_index) {
158*3da8d17dSfengbojiang(姜凤波)             ngx_free(change_index);
159*3da8d17dSfengbojiang(姜凤波)         }
160*3da8d17dSfengbojiang(姜凤波) 
161*3da8d17dSfengbojiang(姜凤波)         change_index = ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes,
162*3da8d17dSfengbojiang(姜凤波)                                  cycle->log);
163*3da8d17dSfengbojiang(姜凤波)         if (change_index == NULL) {
164*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
165*3da8d17dSfengbojiang(姜凤波)         }
166*3da8d17dSfengbojiang(姜凤波)     }
167*3da8d17dSfengbojiang(姜凤波) 
168*3da8d17dSfengbojiang(姜凤波)     max_changes = dpcf->changes;
169*3da8d17dSfengbojiang(姜凤波) 
170*3da8d17dSfengbojiang(姜凤波)     if (nevents < dpcf->events) {
171*3da8d17dSfengbojiang(姜凤波)         if (event_list) {
172*3da8d17dSfengbojiang(姜凤波)             ngx_free(event_list);
173*3da8d17dSfengbojiang(姜凤波)         }
174*3da8d17dSfengbojiang(姜凤波) 
175*3da8d17dSfengbojiang(姜凤波)         event_list = ngx_alloc(sizeof(struct pollfd) * dpcf->events,
176*3da8d17dSfengbojiang(姜凤波)                                cycle->log);
177*3da8d17dSfengbojiang(姜凤波)         if (event_list == NULL) {
178*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
179*3da8d17dSfengbojiang(姜凤波)         }
180*3da8d17dSfengbojiang(姜凤波)     }
181*3da8d17dSfengbojiang(姜凤波) 
182*3da8d17dSfengbojiang(姜凤波)     nevents = dpcf->events;
183*3da8d17dSfengbojiang(姜凤波) 
184*3da8d17dSfengbojiang(姜凤波)     ngx_io = ngx_os_io;
185*3da8d17dSfengbojiang(姜凤波) 
186*3da8d17dSfengbojiang(姜凤波)     ngx_event_actions = ngx_devpoll_module_ctx.actions;
187*3da8d17dSfengbojiang(姜凤波) 
188*3da8d17dSfengbojiang(姜凤波)     ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT;
189*3da8d17dSfengbojiang(姜凤波) 
190*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
191*3da8d17dSfengbojiang(姜凤波) }
192*3da8d17dSfengbojiang(姜凤波) 
193*3da8d17dSfengbojiang(姜凤波) 
194*3da8d17dSfengbojiang(姜凤波) static void
ngx_devpoll_done(ngx_cycle_t * cycle)195*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_done(ngx_cycle_t *cycle)
196*3da8d17dSfengbojiang(姜凤波) {
197*3da8d17dSfengbojiang(姜凤波)     if (close(dp) == -1) {
198*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
199*3da8d17dSfengbojiang(姜凤波)                       "close(/dev/poll) failed");
200*3da8d17dSfengbojiang(姜凤波)     }
201*3da8d17dSfengbojiang(姜凤波) 
202*3da8d17dSfengbojiang(姜凤波)     dp = -1;
203*3da8d17dSfengbojiang(姜凤波) 
204*3da8d17dSfengbojiang(姜凤波)     ngx_free(change_list);
205*3da8d17dSfengbojiang(姜凤波)     ngx_free(event_list);
206*3da8d17dSfengbojiang(姜凤波)     ngx_free(change_index);
207*3da8d17dSfengbojiang(姜凤波) 
208*3da8d17dSfengbojiang(姜凤波)     change_list = NULL;
209*3da8d17dSfengbojiang(姜凤波)     event_list = NULL;
210*3da8d17dSfengbojiang(姜凤波)     change_index = NULL;
211*3da8d17dSfengbojiang(姜凤波)     max_changes = 0;
212*3da8d17dSfengbojiang(姜凤波)     nchanges = 0;
213*3da8d17dSfengbojiang(姜凤波)     nevents = 0;
214*3da8d17dSfengbojiang(姜凤波) }
215*3da8d17dSfengbojiang(姜凤波) 
216*3da8d17dSfengbojiang(姜凤波) 
217*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_devpoll_add_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)218*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
219*3da8d17dSfengbojiang(姜凤波) {
220*3da8d17dSfengbojiang(姜凤波) #if (NGX_DEBUG)
221*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t *c;
222*3da8d17dSfengbojiang(姜凤波) #endif
223*3da8d17dSfengbojiang(姜凤波) 
224*3da8d17dSfengbojiang(姜凤波) #if (NGX_READ_EVENT != POLLIN)
225*3da8d17dSfengbojiang(姜凤波)     event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
226*3da8d17dSfengbojiang(姜凤波) #endif
227*3da8d17dSfengbojiang(姜凤波) 
228*3da8d17dSfengbojiang(姜凤波) #if (NGX_DEBUG)
229*3da8d17dSfengbojiang(姜凤波)     c = ev->data;
230*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
231*3da8d17dSfengbojiang(姜凤波)                    "devpoll add event: fd:%d ev:%04Xi", c->fd, event);
232*3da8d17dSfengbojiang(姜凤波) #endif
233*3da8d17dSfengbojiang(姜凤波) 
234*3da8d17dSfengbojiang(姜凤波)     ev->active = 1;
235*3da8d17dSfengbojiang(姜凤波) 
236*3da8d17dSfengbojiang(姜凤波)     return ngx_devpoll_set_event(ev, event, 0);
237*3da8d17dSfengbojiang(姜凤波) }
238*3da8d17dSfengbojiang(姜凤波) 
239*3da8d17dSfengbojiang(姜凤波) 
240*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_devpoll_del_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)241*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
242*3da8d17dSfengbojiang(姜凤波) {
243*3da8d17dSfengbojiang(姜凤波)     ngx_event_t       *e;
244*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t  *c;
245*3da8d17dSfengbojiang(姜凤波) 
246*3da8d17dSfengbojiang(姜凤波)     c = ev->data;
247*3da8d17dSfengbojiang(姜凤波) 
248*3da8d17dSfengbojiang(姜凤波) #if (NGX_READ_EVENT != POLLIN)
249*3da8d17dSfengbojiang(姜凤波)     event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
250*3da8d17dSfengbojiang(姜凤波) #endif
251*3da8d17dSfengbojiang(姜凤波) 
252*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
253*3da8d17dSfengbojiang(姜凤波)                    "devpoll del event: fd:%d ev:%04Xi", c->fd, event);
254*3da8d17dSfengbojiang(姜凤波) 
255*3da8d17dSfengbojiang(姜凤波)     if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) {
256*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
257*3da8d17dSfengbojiang(姜凤波)     }
258*3da8d17dSfengbojiang(姜凤波) 
259*3da8d17dSfengbojiang(姜凤波)     ev->active = 0;
260*3da8d17dSfengbojiang(姜凤波) 
261*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_CLOSE_EVENT) {
262*3da8d17dSfengbojiang(姜凤波)         e = (event == POLLIN) ? c->write : c->read;
263*3da8d17dSfengbojiang(姜凤波) 
264*3da8d17dSfengbojiang(姜凤波)         if (e) {
265*3da8d17dSfengbojiang(姜凤波)             e->active = 0;
266*3da8d17dSfengbojiang(姜凤波)         }
267*3da8d17dSfengbojiang(姜凤波) 
268*3da8d17dSfengbojiang(姜凤波)         return NGX_OK;
269*3da8d17dSfengbojiang(姜凤波)     }
270*3da8d17dSfengbojiang(姜凤波) 
271*3da8d17dSfengbojiang(姜凤波)     /* restore the pair event if it exists */
272*3da8d17dSfengbojiang(姜凤波) 
273*3da8d17dSfengbojiang(姜凤波)     if (event == POLLIN) {
274*3da8d17dSfengbojiang(姜凤波)         e = c->write;
275*3da8d17dSfengbojiang(姜凤波)         event = POLLOUT;
276*3da8d17dSfengbojiang(姜凤波) 
277*3da8d17dSfengbojiang(姜凤波)     } else {
278*3da8d17dSfengbojiang(姜凤波)         e = c->read;
279*3da8d17dSfengbojiang(姜凤波)         event = POLLIN;
280*3da8d17dSfengbojiang(姜凤波)     }
281*3da8d17dSfengbojiang(姜凤波) 
282*3da8d17dSfengbojiang(姜凤波)     if (e && e->active) {
283*3da8d17dSfengbojiang(姜凤波)         return ngx_devpoll_set_event(e, event, 0);
284*3da8d17dSfengbojiang(姜凤波)     }
285*3da8d17dSfengbojiang(姜凤波) 
286*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
287*3da8d17dSfengbojiang(姜凤波) }
288*3da8d17dSfengbojiang(姜凤波) 
289*3da8d17dSfengbojiang(姜凤波) 
290*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_devpoll_set_event(ngx_event_t * ev,ngx_int_t event,ngx_uint_t flags)291*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
292*3da8d17dSfengbojiang(姜凤波) {
293*3da8d17dSfengbojiang(姜凤波)     size_t             n;
294*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t  *c;
295*3da8d17dSfengbojiang(姜凤波) 
296*3da8d17dSfengbojiang(姜凤波)     c = ev->data;
297*3da8d17dSfengbojiang(姜凤波) 
298*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
299*3da8d17dSfengbojiang(姜凤波)                    "devpoll fd:%d ev:%04Xi fl:%04Xi", c->fd, event, flags);
300*3da8d17dSfengbojiang(姜凤波) 
301*3da8d17dSfengbojiang(姜凤波)     if (nchanges >= max_changes) {
302*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_WARN, ev->log, 0,
303*3da8d17dSfengbojiang(姜凤波)                       "/dev/pool change list is filled up");
304*3da8d17dSfengbojiang(姜凤波) 
305*3da8d17dSfengbojiang(姜凤波)         n = nchanges * sizeof(struct pollfd);
306*3da8d17dSfengbojiang(姜凤波)         if (write(dp, change_list, n) != (ssize_t) n) {
307*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
308*3da8d17dSfengbojiang(姜凤波)                           "write(/dev/poll) failed");
309*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
310*3da8d17dSfengbojiang(姜凤波)         }
311*3da8d17dSfengbojiang(姜凤波) 
312*3da8d17dSfengbojiang(姜凤波)         nchanges = 0;
313*3da8d17dSfengbojiang(姜凤波)     }
314*3da8d17dSfengbojiang(姜凤波) 
315*3da8d17dSfengbojiang(姜凤波)     change_list[nchanges].fd = c->fd;
316*3da8d17dSfengbojiang(姜凤波)     change_list[nchanges].events = (short) event;
317*3da8d17dSfengbojiang(姜凤波)     change_list[nchanges].revents = 0;
318*3da8d17dSfengbojiang(姜凤波) 
319*3da8d17dSfengbojiang(姜凤波)     change_index[nchanges] = ev;
320*3da8d17dSfengbojiang(姜凤波)     ev->index = nchanges;
321*3da8d17dSfengbojiang(姜凤波) 
322*3da8d17dSfengbojiang(姜凤波)     nchanges++;
323*3da8d17dSfengbojiang(姜凤波) 
324*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_CLOSE_EVENT) {
325*3da8d17dSfengbojiang(姜凤波)         n = nchanges * sizeof(struct pollfd);
326*3da8d17dSfengbojiang(姜凤波)         if (write(dp, change_list, n) != (ssize_t) n) {
327*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
328*3da8d17dSfengbojiang(姜凤波)                           "write(/dev/poll) failed");
329*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
330*3da8d17dSfengbojiang(姜凤波)         }
331*3da8d17dSfengbojiang(姜凤波) 
332*3da8d17dSfengbojiang(姜凤波)         nchanges = 0;
333*3da8d17dSfengbojiang(姜凤波)     }
334*3da8d17dSfengbojiang(姜凤波) 
335*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
336*3da8d17dSfengbojiang(姜凤波) }
337*3da8d17dSfengbojiang(姜凤波) 
338*3da8d17dSfengbojiang(姜凤波) 
339*3da8d17dSfengbojiang(姜凤波) static ngx_int_t
ngx_devpoll_process_events(ngx_cycle_t * cycle,ngx_msec_t timer,ngx_uint_t flags)340*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
341*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t flags)
342*3da8d17dSfengbojiang(姜凤波) {
343*3da8d17dSfengbojiang(姜凤波)     int                 events, revents, rc;
344*3da8d17dSfengbojiang(姜凤波)     size_t              n;
345*3da8d17dSfengbojiang(姜凤波)     ngx_fd_t            fd;
346*3da8d17dSfengbojiang(姜凤波)     ngx_err_t           err;
347*3da8d17dSfengbojiang(姜凤波)     ngx_int_t           i;
348*3da8d17dSfengbojiang(姜凤波)     ngx_uint_t          level, instance;
349*3da8d17dSfengbojiang(姜凤波)     ngx_event_t        *rev, *wev;
350*3da8d17dSfengbojiang(姜凤波)     ngx_queue_t        *queue;
351*3da8d17dSfengbojiang(姜凤波)     ngx_connection_t   *c;
352*3da8d17dSfengbojiang(姜凤波)     struct pollfd       pfd;
353*3da8d17dSfengbojiang(姜凤波)     struct dvpoll       dvp;
354*3da8d17dSfengbojiang(姜凤波) 
355*3da8d17dSfengbojiang(姜凤波)     /* NGX_TIMER_INFINITE == INFTIM */
356*3da8d17dSfengbojiang(姜凤波) 
357*3da8d17dSfengbojiang(姜凤波)     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
358*3da8d17dSfengbojiang(姜凤波)                    "devpoll timer: %M", timer);
359*3da8d17dSfengbojiang(姜凤波) 
360*3da8d17dSfengbojiang(姜凤波)     if (nchanges) {
361*3da8d17dSfengbojiang(姜凤波)         n = nchanges * sizeof(struct pollfd);
362*3da8d17dSfengbojiang(姜凤波)         if (write(dp, change_list, n) != (ssize_t) n) {
363*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
364*3da8d17dSfengbojiang(姜凤波)                           "write(/dev/poll) failed");
365*3da8d17dSfengbojiang(姜凤波)             return NGX_ERROR;
366*3da8d17dSfengbojiang(姜凤波)         }
367*3da8d17dSfengbojiang(姜凤波) 
368*3da8d17dSfengbojiang(姜凤波)         nchanges = 0;
369*3da8d17dSfengbojiang(姜凤波)     }
370*3da8d17dSfengbojiang(姜凤波) 
371*3da8d17dSfengbojiang(姜凤波)     dvp.dp_fds = event_list;
372*3da8d17dSfengbojiang(姜凤波)     dvp.dp_nfds = (int) nevents;
373*3da8d17dSfengbojiang(姜凤波)     dvp.dp_timeout = timer;
374*3da8d17dSfengbojiang(姜凤波)     events = ioctl(dp, DP_POLL, &dvp);
375*3da8d17dSfengbojiang(姜凤波) 
376*3da8d17dSfengbojiang(姜凤波)     err = (events == -1) ? ngx_errno : 0;
377*3da8d17dSfengbojiang(姜凤波) 
378*3da8d17dSfengbojiang(姜凤波)     if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
379*3da8d17dSfengbojiang(姜凤波)         ngx_time_update();
380*3da8d17dSfengbojiang(姜凤波)     }
381*3da8d17dSfengbojiang(姜凤波) 
382*3da8d17dSfengbojiang(姜凤波)     if (err) {
383*3da8d17dSfengbojiang(姜凤波)         if (err == NGX_EINTR) {
384*3da8d17dSfengbojiang(姜凤波) 
385*3da8d17dSfengbojiang(姜凤波)             if (ngx_event_timer_alarm) {
386*3da8d17dSfengbojiang(姜凤波)                 ngx_event_timer_alarm = 0;
387*3da8d17dSfengbojiang(姜凤波)                 return NGX_OK;
388*3da8d17dSfengbojiang(姜凤波)             }
389*3da8d17dSfengbojiang(姜凤波) 
390*3da8d17dSfengbojiang(姜凤波)             level = NGX_LOG_INFO;
391*3da8d17dSfengbojiang(姜凤波) 
392*3da8d17dSfengbojiang(姜凤波)         } else {
393*3da8d17dSfengbojiang(姜凤波)             level = NGX_LOG_ALERT;
394*3da8d17dSfengbojiang(姜凤波)         }
395*3da8d17dSfengbojiang(姜凤波) 
396*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(level, cycle->log, err, "ioctl(DP_POLL) failed");
397*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
398*3da8d17dSfengbojiang(姜凤波)     }
399*3da8d17dSfengbojiang(姜凤波) 
400*3da8d17dSfengbojiang(姜凤波)     if (events == 0) {
401*3da8d17dSfengbojiang(姜凤波)         if (timer != NGX_TIMER_INFINITE) {
402*3da8d17dSfengbojiang(姜凤波)             return NGX_OK;
403*3da8d17dSfengbojiang(姜凤波)         }
404*3da8d17dSfengbojiang(姜凤波) 
405*3da8d17dSfengbojiang(姜凤波)         ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
406*3da8d17dSfengbojiang(姜凤波)                       "ioctl(DP_POLL) returned no events without timeout");
407*3da8d17dSfengbojiang(姜凤波)         return NGX_ERROR;
408*3da8d17dSfengbojiang(姜凤波)     }
409*3da8d17dSfengbojiang(姜凤波) 
410*3da8d17dSfengbojiang(姜凤波)     for (i = 0; i < events; i++) {
411*3da8d17dSfengbojiang(姜凤波) 
412*3da8d17dSfengbojiang(姜凤波)         fd = event_list[i].fd;
413*3da8d17dSfengbojiang(姜凤波)         revents = event_list[i].revents;
414*3da8d17dSfengbojiang(姜凤波) 
415*3da8d17dSfengbojiang(姜凤波)         c = ngx_cycle->files[fd];
416*3da8d17dSfengbojiang(姜凤波) 
417*3da8d17dSfengbojiang(姜凤波)         if (c == NULL || c->fd == -1) {
418*3da8d17dSfengbojiang(姜凤波) 
419*3da8d17dSfengbojiang(姜凤波)             pfd.fd = fd;
420*3da8d17dSfengbojiang(姜凤波)             pfd.events = 0;
421*3da8d17dSfengbojiang(姜凤波)             pfd.revents = 0;
422*3da8d17dSfengbojiang(姜凤波) 
423*3da8d17dSfengbojiang(姜凤波)             rc = ioctl(dp, DP_ISPOLLED, &pfd);
424*3da8d17dSfengbojiang(姜凤波) 
425*3da8d17dSfengbojiang(姜凤波)             switch (rc) {
426*3da8d17dSfengbojiang(姜凤波) 
427*3da8d17dSfengbojiang(姜凤波)             case -1:
428*3da8d17dSfengbojiang(姜凤波)                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
429*3da8d17dSfengbojiang(姜凤波)                     "ioctl(DP_ISPOLLED) failed for socket %d, event %04Xd",
430*3da8d17dSfengbojiang(姜凤波)                     fd, revents);
431*3da8d17dSfengbojiang(姜凤波)                 break;
432*3da8d17dSfengbojiang(姜凤波) 
433*3da8d17dSfengbojiang(姜凤波)             case 0:
434*3da8d17dSfengbojiang(姜凤波)                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
435*3da8d17dSfengbojiang(姜凤波)                     "phantom event %04Xd for closed and removed socket %d",
436*3da8d17dSfengbojiang(姜凤波)                     revents, fd);
437*3da8d17dSfengbojiang(姜凤波)                 break;
438*3da8d17dSfengbojiang(姜凤波) 
439*3da8d17dSfengbojiang(姜凤波)             default:
440*3da8d17dSfengbojiang(姜凤波)                 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
441*3da8d17dSfengbojiang(姜凤波)                     "unexpected event %04Xd for closed and removed socket %d, "
442*3da8d17dSfengbojiang(姜凤波)                     "ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
443*3da8d17dSfengbojiang(姜凤波)                     revents, fd, rc, pfd.fd, pfd.revents);
444*3da8d17dSfengbojiang(姜凤波) 
445*3da8d17dSfengbojiang(姜凤波)                 pfd.fd = fd;
446*3da8d17dSfengbojiang(姜凤波)                 pfd.events = POLLREMOVE;
447*3da8d17dSfengbojiang(姜凤波)                 pfd.revents = 0;
448*3da8d17dSfengbojiang(姜凤波) 
449*3da8d17dSfengbojiang(姜凤波)                 if (write(dp, &pfd, sizeof(struct pollfd))
450*3da8d17dSfengbojiang(姜凤波)                     != (ssize_t) sizeof(struct pollfd))
451*3da8d17dSfengbojiang(姜凤波)                 {
452*3da8d17dSfengbojiang(姜凤波)                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
453*3da8d17dSfengbojiang(姜凤波)                                   "write(/dev/poll) for %d failed", fd);
454*3da8d17dSfengbojiang(姜凤波)                 }
455*3da8d17dSfengbojiang(姜凤波) 
456*3da8d17dSfengbojiang(姜凤波)                 if (close(fd) == -1) {
457*3da8d17dSfengbojiang(姜凤波)                     ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
458*3da8d17dSfengbojiang(姜凤波)                                   "close(%d) failed", fd);
459*3da8d17dSfengbojiang(姜凤波)                 }
460*3da8d17dSfengbojiang(姜凤波) 
461*3da8d17dSfengbojiang(姜凤波)                 break;
462*3da8d17dSfengbojiang(姜凤波)             }
463*3da8d17dSfengbojiang(姜凤波) 
464*3da8d17dSfengbojiang(姜凤波)             continue;
465*3da8d17dSfengbojiang(姜凤波)         }
466*3da8d17dSfengbojiang(姜凤波) 
467*3da8d17dSfengbojiang(姜凤波)         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
468*3da8d17dSfengbojiang(姜凤波)                        "devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
469*3da8d17dSfengbojiang(姜凤波)                        fd, event_list[i].events, revents);
470*3da8d17dSfengbojiang(姜凤波) 
471*3da8d17dSfengbojiang(姜凤波)         if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
472*3da8d17dSfengbojiang(姜凤波)             ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
473*3da8d17dSfengbojiang(姜凤波)                           "ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd",
474*3da8d17dSfengbojiang(姜凤波)                           fd, event_list[i].events, revents);
475*3da8d17dSfengbojiang(姜凤波)         }
476*3da8d17dSfengbojiang(姜凤波) 
477*3da8d17dSfengbojiang(姜凤波)         if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
478*3da8d17dSfengbojiang(姜凤波)             ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
479*3da8d17dSfengbojiang(姜凤波)                           "strange ioctl(DP_POLL) events "
480*3da8d17dSfengbojiang(姜凤波)                           "fd:%d ev:%04Xd rev:%04Xd",
481*3da8d17dSfengbojiang(姜凤波)                           fd, event_list[i].events, revents);
482*3da8d17dSfengbojiang(姜凤波)         }
483*3da8d17dSfengbojiang(姜凤波) 
484*3da8d17dSfengbojiang(姜凤波)         if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
485*3da8d17dSfengbojiang(姜凤波) 
486*3da8d17dSfengbojiang(姜凤波)             /*
487*3da8d17dSfengbojiang(姜凤波)              * if the error events were returned, add POLLIN and POLLOUT
488*3da8d17dSfengbojiang(姜凤波)              * to handle the events at least in one active handler
489*3da8d17dSfengbojiang(姜凤波)              */
490*3da8d17dSfengbojiang(姜凤波) 
491*3da8d17dSfengbojiang(姜凤波)             revents |= POLLIN|POLLOUT;
492*3da8d17dSfengbojiang(姜凤波)         }
493*3da8d17dSfengbojiang(姜凤波) 
494*3da8d17dSfengbojiang(姜凤波)         rev = c->read;
495*3da8d17dSfengbojiang(姜凤波) 
496*3da8d17dSfengbojiang(姜凤波)         if ((revents & POLLIN) && rev->active) {
497*3da8d17dSfengbojiang(姜凤波)             rev->ready = 1;
498*3da8d17dSfengbojiang(姜凤波) 
499*3da8d17dSfengbojiang(姜凤波)             if (flags & NGX_POST_EVENTS) {
500*3da8d17dSfengbojiang(姜凤波)                 queue = rev->accept ? &ngx_posted_accept_events
501*3da8d17dSfengbojiang(姜凤波)                                     : &ngx_posted_events;
502*3da8d17dSfengbojiang(姜凤波) 
503*3da8d17dSfengbojiang(姜凤波)                 ngx_post_event(rev, queue);
504*3da8d17dSfengbojiang(姜凤波) 
505*3da8d17dSfengbojiang(姜凤波)             } else {
506*3da8d17dSfengbojiang(姜凤波)                 instance = rev->instance;
507*3da8d17dSfengbojiang(姜凤波) 
508*3da8d17dSfengbojiang(姜凤波)                 rev->handler(rev);
509*3da8d17dSfengbojiang(姜凤波) 
510*3da8d17dSfengbojiang(姜凤波)                 if (c->fd == -1 || rev->instance != instance) {
511*3da8d17dSfengbojiang(姜凤波)                     continue;
512*3da8d17dSfengbojiang(姜凤波)                 }
513*3da8d17dSfengbojiang(姜凤波)             }
514*3da8d17dSfengbojiang(姜凤波)         }
515*3da8d17dSfengbojiang(姜凤波) 
516*3da8d17dSfengbojiang(姜凤波)         wev = c->write;
517*3da8d17dSfengbojiang(姜凤波) 
518*3da8d17dSfengbojiang(姜凤波)         if ((revents & POLLOUT) && wev->active) {
519*3da8d17dSfengbojiang(姜凤波)             wev->ready = 1;
520*3da8d17dSfengbojiang(姜凤波) 
521*3da8d17dSfengbojiang(姜凤波)             if (flags & NGX_POST_EVENTS) {
522*3da8d17dSfengbojiang(姜凤波)                 ngx_post_event(wev, &ngx_posted_events);
523*3da8d17dSfengbojiang(姜凤波) 
524*3da8d17dSfengbojiang(姜凤波)             } else {
525*3da8d17dSfengbojiang(姜凤波)                 wev->handler(wev);
526*3da8d17dSfengbojiang(姜凤波)             }
527*3da8d17dSfengbojiang(姜凤波)         }
528*3da8d17dSfengbojiang(姜凤波)     }
529*3da8d17dSfengbojiang(姜凤波) 
530*3da8d17dSfengbojiang(姜凤波)     return NGX_OK;
531*3da8d17dSfengbojiang(姜凤波) }
532*3da8d17dSfengbojiang(姜凤波) 
533*3da8d17dSfengbojiang(姜凤波) 
534*3da8d17dSfengbojiang(姜凤波) static void *
ngx_devpoll_create_conf(ngx_cycle_t * cycle)535*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_create_conf(ngx_cycle_t *cycle)
536*3da8d17dSfengbojiang(姜凤波) {
537*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_conf_t  *dpcf;
538*3da8d17dSfengbojiang(姜凤波) 
539*3da8d17dSfengbojiang(姜凤波)     dpcf = ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t));
540*3da8d17dSfengbojiang(姜凤波)     if (dpcf == NULL) {
541*3da8d17dSfengbojiang(姜凤波)         return NULL;
542*3da8d17dSfengbojiang(姜凤波)     }
543*3da8d17dSfengbojiang(姜凤波) 
544*3da8d17dSfengbojiang(姜凤波)     dpcf->changes = NGX_CONF_UNSET;
545*3da8d17dSfengbojiang(姜凤波)     dpcf->events = NGX_CONF_UNSET;
546*3da8d17dSfengbojiang(姜凤波) 
547*3da8d17dSfengbojiang(姜凤波)     return dpcf;
548*3da8d17dSfengbojiang(姜凤波) }
549*3da8d17dSfengbojiang(姜凤波) 
550*3da8d17dSfengbojiang(姜凤波) 
551*3da8d17dSfengbojiang(姜凤波) static char *
ngx_devpoll_init_conf(ngx_cycle_t * cycle,void * conf)552*3da8d17dSfengbojiang(姜凤波) ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf)
553*3da8d17dSfengbojiang(姜凤波) {
554*3da8d17dSfengbojiang(姜凤波)     ngx_devpoll_conf_t *dpcf = conf;
555*3da8d17dSfengbojiang(姜凤波) 
556*3da8d17dSfengbojiang(姜凤波)     ngx_conf_init_uint_value(dpcf->changes, 32);
557*3da8d17dSfengbojiang(姜凤波)     ngx_conf_init_uint_value(dpcf->events, 32);
558*3da8d17dSfengbojiang(姜凤波) 
559*3da8d17dSfengbojiang(姜凤波)     return NGX_CONF_OK;
560*3da8d17dSfengbojiang(姜凤波) }
561