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