Mercurial > hg > nginx-vendor-current
comparison src/event/modules/ngx_aio_module.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 46833bd150cb |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0b350454894 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 #include <ngx_aio.h> | |
11 | |
12 #if (HAVE_KQUEUE) | |
13 #include <ngx_kqueue_module.h> | |
14 #endif | |
15 | |
16 | |
17 static int ngx_aio_init(ngx_cycle_t *cycle); | |
18 static void ngx_aio_done(ngx_cycle_t *cycle); | |
19 static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags); | |
20 static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags); | |
21 static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags); | |
22 static int ngx_aio_process_events(ngx_cycle_t *cycle); | |
23 | |
24 | |
25 ngx_os_io_t ngx_os_aio = { | |
26 ngx_aio_read, | |
27 ngx_aio_read_chain, | |
28 ngx_aio_write, | |
29 ngx_aio_write_chain, | |
30 NGX_HAVE_ZEROCOPY | |
31 }; | |
32 | |
33 | |
34 static ngx_str_t aio_name = ngx_string("aio"); | |
35 | |
36 ngx_event_module_t ngx_aio_module_ctx = { | |
37 &aio_name, | |
38 NULL, /* create configuration */ | |
39 NULL, /* init configuration */ | |
40 | |
41 { | |
42 ngx_aio_add_event, /* add an event */ | |
43 ngx_aio_del_event, /* delete an event */ | |
44 NULL, /* enable an event */ | |
45 NULL, /* disable an event */ | |
46 NULL, /* add an connection */ | |
47 ngx_aio_del_connection, /* delete an connection */ | |
48 NULL, /* process the changes */ | |
49 ngx_aio_process_events, /* process the events */ | |
50 ngx_aio_init, /* init the events */ | |
51 ngx_aio_done /* done the events */ | |
52 } | |
53 | |
54 }; | |
55 | |
56 ngx_module_t ngx_aio_module = { | |
57 NGX_MODULE, | |
58 &ngx_aio_module_ctx, /* module context */ | |
59 NULL, /* module directives */ | |
60 NGX_EVENT_MODULE, /* module type */ | |
61 NULL, /* init module */ | |
62 NULL /* init process */ | |
63 }; | |
64 | |
65 | |
66 | |
67 #if (HAVE_KQUEUE) | |
68 | |
69 static int ngx_aio_init(ngx_cycle_t *cycle) | |
70 { | |
71 if (ngx_kqueue_module_ctx.actions.init(cycle) == NGX_ERROR) { | |
72 return NGX_ERROR; | |
73 } | |
74 | |
75 ngx_io = ngx_os_aio; | |
76 | |
77 ngx_event_flags = NGX_USE_AIO_EVENT; | |
78 ngx_event_actions = ngx_aio_module_ctx.actions; | |
79 | |
80 | |
81 return NGX_OK; | |
82 } | |
83 | |
84 | |
85 static void ngx_aio_done(ngx_cycle_t *cycle) | |
86 { | |
87 ngx_kqueue_module_ctx.actions.done(cycle); | |
88 } | |
89 | |
90 | |
91 /* The event adding and deleting are needed for the listening sockets */ | |
92 | |
93 static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags) | |
94 { | |
95 return ngx_kqueue_module_ctx.actions.add(ev, event, flags); | |
96 } | |
97 | |
98 | |
99 static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags) | |
100 { | |
101 return ngx_kqueue_module_ctx.actions.del(ev, event, flags); | |
102 } | |
103 | |
104 | |
105 static int ngx_aio_del_connection(ngx_connection_t *c, u_int flags) | |
106 { | |
107 int rc; | |
108 | |
109 if (c->read->active == 0 && c->write->active == 0) { | |
110 return NGX_OK; | |
111 } | |
112 | |
113 rc = aio_cancel(c->fd, NULL); | |
114 | |
115 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc); | |
116 | |
117 if (rc == AIO_CANCELED) { | |
118 c->read->active = c->write->active = 0; | |
119 return NGX_OK; | |
120 } | |
121 | |
122 if (rc == AIO_ALLDONE) { | |
123 c->read->active = c->write->active = 0; | |
124 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
125 "aio_cancel() returned AIO_ALLDONE"); | |
126 return NGX_OK; | |
127 } | |
128 | |
129 if (rc == -1) { | |
130 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, | |
131 "aio_cancel() failed"); | |
132 return NGX_ERROR; | |
133 } | |
134 | |
135 if (rc == AIO_NOTCANCELED) { | |
136 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
137 "aio_cancel() returned AIO_NOTCANCELED"); | |
138 | |
139 return NGX_ERROR; | |
140 } | |
141 | |
142 return NGX_OK; | |
143 } | |
144 | |
145 | |
146 static int ngx_aio_process_events(ngx_cycle_t *cycle) | |
147 { | |
148 return ngx_kqueue_module_ctx.actions.process_events(cycle); | |
149 } | |
150 | |
151 #endif /* HAVE_KQUEUE */ | |
152 | |
153 | |
154 #if 0 | |
155 | |
156 /* 1 */ | |
157 int ngx_posix_aio_process_events(ngx_log_t *log) | |
158 { | |
159 listen via SIGIO; | |
160 aio_* via SIGxxx; | |
161 | |
162 sigsuspend()/sigwaitinfo()/sigtimedwait(); | |
163 } | |
164 | |
165 /* 2 */ | |
166 int ngx_posix_aio_process_events(ngx_log_t *log) | |
167 { | |
168 unmask signal | |
169 | |
170 listen via SIGIO; | |
171 | |
172 /* BUG: SIGIO can be delivered before aio_*() */ | |
173 | |
174 aio_suspend()/aiowait()/aio_waitcomplete() with timeout | |
175 | |
176 mask signal | |
177 | |
178 if (ngx_socket_errno == NGX_EINTR) | |
179 look listen | |
180 select()/accept() nb listen sockets | |
181 else | |
182 aio | |
183 } | |
184 | |
185 /* 3 */ | |
186 int ngx_posix_aio_process_events(ngx_log_t *log) | |
187 { | |
188 #if 0 | |
189 unmask signal | |
190 | |
191 /* BUG: AIO signal can be delivered before select() */ | |
192 | |
193 select(listen); | |
194 | |
195 mask signal | |
196 #endif | |
197 | |
198 pselect(listen, mask); | |
199 | |
200 if (ngx_socket_errno == NGX_EINTR) | |
201 look ready array | |
202 } | |
203 | |
204 void aio_sig_handler(int signo, siginfo_t *siginfo, void *context) | |
205 { | |
206 push siginfo->si_value.sival_ptr | |
207 } | |
208 | |
209 #endif |