Mercurial > hg > nginx-quic
comparison src/event/modules/ngx_rtsig_module.c @ 260:5dacbb4daaf6
nginx-0.0.2-2004-02-17-20:53:12 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 17 Feb 2004 17:53:12 +0000 |
parents | src/event/modules/ngx_sigio_module.c@008276b9e061 |
children | bdd631bf1a1c |
comparison
equal
deleted
inserted
replaced
259:d30f2c39caae | 260:5dacbb4daaf6 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) 2002-2004 Igor Sysoev, http://sysoev.ru/en/ | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 | |
11 | |
12 #if (TEST_BUILD_RTSIG) | |
13 | |
14 #define F_SETSIG 10 | |
15 #define SIGRTMIN 33 | |
16 #define si_fd __spare__[0] | |
17 | |
18 int sigwaitinfo(const sigset_t *set, siginfo_t *info); | |
19 | |
20 int sigtimedwait(const sigset_t *set, siginfo_t *info, | |
21 const struct timespec *timeout); | |
22 | |
23 int sigwaitinfo(const sigset_t *set, siginfo_t *info) | |
24 { | |
25 return -1; | |
26 } | |
27 | |
28 int sigtimedwait(const sigset_t *set, siginfo_t *info, | |
29 const struct timespec *timeout) | |
30 { | |
31 return -1; | |
32 } | |
33 | |
34 #endif | |
35 | |
36 | |
37 typedef struct { | |
38 int signo; | |
39 } ngx_rtsig_conf_t; | |
40 | |
41 | |
42 static int ngx_rtsig_init(ngx_cycle_t *cycle); | |
43 static void ngx_rtsig_done(ngx_cycle_t *cycle); | |
44 static int ngx_rtsig_add_connection(ngx_connection_t *c); | |
45 static int ngx_rtsig_del_connection(ngx_connection_t *c); | |
46 static int ngx_rtsig_process_events(ngx_log_t *log); | |
47 | |
48 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); | |
49 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); | |
50 | |
51 | |
52 static sigset_t set; | |
53 | |
54 | |
55 static ngx_str_t rtsig_name = ngx_string("rtsig"); | |
56 | |
57 static ngx_command_t ngx_rtsig_commands[] = { | |
58 | |
59 {ngx_string("rtsig_signo"), | |
60 NGX_EVENT_CONF|NGX_CONF_TAKE1, | |
61 ngx_conf_set_num_slot, | |
62 0, | |
63 offsetof(ngx_rtsig_conf_t, signo), | |
64 NULL}, | |
65 | |
66 ngx_null_command | |
67 }; | |
68 | |
69 | |
70 ngx_event_module_t ngx_rtsig_module_ctx = { | |
71 &rtsig_name, | |
72 ngx_rtsig_create_conf, /* create configuration */ | |
73 ngx_rtsig_init_conf, /* init configuration */ | |
74 | |
75 { | |
76 NULL, /* add an event */ | |
77 NULL, /* delete an event */ | |
78 NULL, /* enable an event */ | |
79 NULL, /* disable an event */ | |
80 ngx_rtsig_add_connection, /* add an connection */ | |
81 ngx_rtsig_del_connection, /* delete an connection */ | |
82 ngx_rtsig_process_events, /* process the events */ | |
83 ngx_rtsig_init, /* init the events */ | |
84 ngx_rtsig_done, /* done the events */ | |
85 } | |
86 | |
87 }; | |
88 | |
89 ngx_module_t ngx_rtsig_module = { | |
90 NGX_MODULE, | |
91 &ngx_rtsig_module_ctx, /* module context */ | |
92 ngx_rtsig_commands, /* module directives */ | |
93 NGX_EVENT_MODULE, /* module type */ | |
94 NULL, /* init module */ | |
95 NULL /* init child */ | |
96 }; | |
97 | |
98 | |
99 static int ngx_rtsig_init(ngx_cycle_t *cycle) | |
100 { | |
101 ngx_rtsig_conf_t *rtscf; | |
102 | |
103 rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module); | |
104 | |
105 sigemptyset(&set); | |
106 sigaddset(&set, rtscf->signo); | |
107 sigaddset(&set, SIGIO); | |
108 | |
109 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { | |
110 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
111 "sigprocmask() failed"); | |
112 return NGX_ERROR; | |
113 } | |
114 | |
115 ngx_io = ngx_os_io; | |
116 | |
117 ngx_event_actions = ngx_rtsig_module_ctx.actions; | |
118 | |
119 ngx_event_flags = NGX_USE_SIGIO_EVENT; | |
120 | |
121 return NGX_OK; | |
122 } | |
123 | |
124 | |
125 static void ngx_rtsig_done(ngx_cycle_t *cycle) | |
126 { | |
127 } | |
128 | |
129 | |
130 static int ngx_rtsig_add_connection(ngx_connection_t *c) | |
131 { | |
132 ngx_rtsig_conf_t *rtscf; | |
133 | |
134 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); | |
135 | |
136 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
137 "rtsig add connection: fd:%d signo:%d", c->fd, rtscf->signo); | |
138 | |
139 if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) { | |
140 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
141 "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed"); | |
142 return NGX_ERROR; | |
143 } | |
144 | |
145 if (fcntl(c->fd, F_SETSIG, rtscf->signo) == -1) { | |
146 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
147 "fcntl(F_SETSIG) failed"); | |
148 return NGX_ERROR; | |
149 } | |
150 | |
151 if (fcntl(c->fd, F_SETOWN, ngx_getpid()) == -1) { | |
152 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
153 "fcntl(F_SETOWN) failed"); | |
154 return NGX_ERROR; | |
155 } | |
156 | |
157 #if (HAVE_ONESIGFD) | |
158 if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) { | |
159 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
160 "fcntl(F_SETAUXFL) failed"); | |
161 return NGX_ERROR; | |
162 } | |
163 #endif | |
164 | |
165 c->read->active = 1; | |
166 c->write->active = 1; | |
167 | |
168 return NGX_OK; | |
169 } | |
170 | |
171 | |
172 static int ngx_rtsig_del_connection(ngx_connection_t *c) | |
173 { | |
174 c->read->active = 0; | |
175 c->write->active = 0; | |
176 | |
177 return NGX_OK; | |
178 } | |
179 | |
180 | |
181 int ngx_rtsig_process_events(ngx_log_t *log) | |
182 { | |
183 int signo; | |
184 ngx_int_t instance, i; | |
185 size_t n; | |
186 ngx_msec_t timer; | |
187 ngx_err_t err; | |
188 ngx_cycle_t **cycle; | |
189 siginfo_t si; | |
190 struct timeval tv; | |
191 struct timespec ts; | |
192 struct sigaction sa; | |
193 ngx_connection_t *c; | |
194 ngx_epoch_msec_t delta; | |
195 ngx_rtsig_conf_t *rtscf; | |
196 | |
197 timer = ngx_event_find_timer(); | |
198 ngx_old_elapsed_msec = ngx_elapsed_msec; | |
199 | |
200 if (timer) { | |
201 ts.tv_sec = timer / 1000; | |
202 ts.tv_nsec = (timer % 1000) * 1000000; | |
203 } | |
204 | |
205 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, log, 0, "rtsig timer: %d", timer); | |
206 | |
207 if (timer) { | |
208 signo = sigtimedwait(&set, &si, &ts); | |
209 } else { | |
210 signo = sigwaitinfo(&set, &si); | |
211 } | |
212 | |
213 if (signo == -1) { | |
214 err = ngx_errno; | |
215 } else { | |
216 err = 0; | |
217 } | |
218 | |
219 ngx_gettimeofday(&tv); | |
220 ngx_time_update(tv.tv_sec); | |
221 | |
222 delta = ngx_elapsed_msec; | |
223 ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec; | |
224 | |
225 if (signo == -1) { | |
226 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, | |
227 log, err, | |
228 timer ? "sigtimedwait() failed" : "sigwaitinfo() failed"); | |
229 return NGX_ERROR; | |
230 } | |
231 | |
232 if (timer) { | |
233 delta = ngx_elapsed_msec - delta; | |
234 | |
235 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0, | |
236 "rtsig timer: %d, delta: %d", timer, (int) delta); | |
237 } | |
238 | |
239 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0, | |
240 "signo:%d fd:%d band:%X", signo, si.si_fd, si.si_band); | |
241 | |
242 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); | |
243 | |
244 if (signo == rtscf->signo) { | |
245 | |
246 /* TODO: old_cycles */ | |
247 c = &ngx_cycle->connections[si.si_fd]; | |
248 | |
249 /* TODO: stale signals */ | |
250 | |
251 if (si.si_band & (POLLIN|POLLHUP|POLLERR)) { | |
252 if (c->read->active) { | |
253 c->read->ready = 1; | |
254 c->read->event_handler(c->read); | |
255 } | |
256 } | |
257 | |
258 if (si.si_band & (POLLOUT|POLLHUP|POLLERR)) { | |
259 if (c->write->active) { | |
260 c->write->ready = 1; | |
261 c->write->event_handler(c->write); | |
262 } | |
263 } | |
264 | |
265 } else if (signo == SIGIO) { | |
266 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
267 "signal queue overflowed: " | |
268 "SIGIO, fd:%d, band:%X", si.si_fd, si.si_band); | |
269 | |
270 ngx_memzero(&sa, sizeof(struct sigaction)); | |
271 sa.sa_handler = SIG_DFL; | |
272 sigemptyset(&sa.sa_mask); | |
273 if (sigaction(rtscf->signo, &sa, NULL) == -1) { | |
274 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
275 "sigaction(%d, SIG_DFL) failed", rtscf->signo); | |
276 } | |
277 | |
278 } else { | |
279 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
280 timer ? "sigtimedwait() returned unexpected signal: %d": | |
281 "sigwaitinfo() returned unexpected signal: %d", | |
282 signo); | |
283 return NGX_ERROR; | |
284 } | |
285 | |
286 if (timer != (ngx_msec_t) -1 && delta) { | |
287 ngx_event_expire_timers((ngx_msec_t) delta); | |
288 } | |
289 | |
290 return NGX_OK; | |
291 } | |
292 | |
293 | |
294 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle) | |
295 { | |
296 ngx_rtsig_conf_t *rtscf; | |
297 | |
298 ngx_test_null(rtscf, ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t)), | |
299 NGX_CONF_ERROR); | |
300 | |
301 rtscf->signo = NGX_CONF_UNSET; | |
302 | |
303 return rtscf; | |
304 } | |
305 | |
306 | |
307 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf) | |
308 { | |
309 ngx_rtsig_conf_t *rtscf = conf; | |
310 | |
311 /* LinuxThreads use the first 3 RT signals */ | |
312 ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10); | |
313 | |
314 return NGX_CONF_OK; | |
315 } |