comparison src/event/modules/ngx_poll_module.c @ 36:c14d7232b11f

nginx-0.0.1-2002-12-23-09:29:22 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 23 Dec 2002 06:29:22 +0000
parents
children 9fe40e51d4a3
comparison
equal deleted inserted replaced
35:79c1fce18e71 36:c14d7232b11f
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_types.h>
5 #include <ngx_log.h>
6 #include <ngx_time.h>
7 #include <ngx_connection.h>
8 #include <ngx_event.h>
9 #include <ngx_poll_module.h>
10
11
12 /* should be per-thread */
13 static struct pollfd *event_list;
14 static int nevents;
15
16 static ngx_event_t **event_index;
17 static ngx_event_t timer_queue;
18 /* */
19
20 int ngx_poll_init(int max_connections, ngx_log_t *log)
21 {
22 ngx_test_null(event_list,
23 ngx_alloc(sizeof(struct pollfd) * max_connections, log),
24 NGX_ERROR);
25
26 ngx_test_null(event_index,
27 ngx_alloc(sizeof(ngx_event_t *) * max_connections, log),
28 NGX_ERROR);
29
30 nevents = 0;
31
32 timer_queue.timer_prev = &timer_queue;
33 timer_queue.timer_next = &timer_queue;
34
35 ngx_event_actions.add = ngx_poll_add_event;
36 ngx_event_actions.del = ngx_poll_del_event;
37 ngx_event_actions.timer = ngx_poll_add_timer;
38 ngx_event_actions.process = ngx_poll_process_events;
39
40 return NGX_OK;
41 }
42
43 int ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
44 {
45 ngx_event_t *e;
46 ngx_connection_t *c;
47
48 c = (ngx_connection_t *) ev->data;
49
50 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
51
52 if (event == NGX_READ_EVENT) {
53 e = c->write;
54 #if (NGX_READ_EVENT != POLLIN)
55 event = POLLIN;
56 #endif
57
58 } else {
59 e = c->read;
60 #if (NGX_WRITE_EVENT != POLLOUT)
61 event = POLLOUT;
62 #endif
63 }
64
65 ngx_log_debug(ev->log, "poll fd:%d event:%d" _ c->fd _ event);
66
67 if (e == NULL || e->index == NGX_INVALID_INDEX) {
68 event_list[nevents].fd = c->fd;
69 event_list[nevents].events = event;
70 event_list[nevents].revents = 0;
71
72 event_index[nevents] = ev;
73 ev->index = nevents;
74 nevents++;
75
76 } else {
77 event_list[e->index].events |= event;
78 ev->index = e->index;
79 }
80
81 return NGX_OK;
82 }
83
84 int ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
85 {
86 ngx_event_t *e;
87 ngx_connection_t *c;
88
89 c = (ngx_connection_t *) ev->data;
90
91 if (ev->index == NGX_INVALID_INDEX)
92 return NGX_OK;
93
94 if (event == NGX_READ_EVENT) {
95 e = c->write;
96 #if (NGX_READ_EVENT != POLLIN)
97 event = POLLIN;
98 #endif
99
100 } else {
101 e = c->read;
102 #if (NGX_WRITE_EVENT != POLLOUT)
103 event = POLLOUT;
104 #endif
105 }
106
107 ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event);
108
109 if (e == NULL || e->index == NGX_INVALID_INDEX) {
110 if (ev->index < --nevents) {
111 event_index[ev->index] = event_index[nevents];
112 event_index[ev->index]->index = ev->index;
113 }
114
115 } else {
116 event_list[e->index].events &= ~event;
117 }
118
119 ev->index = NGX_INVALID_INDEX;
120
121 return NGX_OK;
122 }
123
124 int ngx_poll_process_events(ngx_log_t *log)
125 {
126 int i, ready, found;
127 u_int timer, delta;
128 ngx_event_t *ev;
129 ngx_connection_t *c;
130
131 if (timer_queue.timer_next != &timer_queue) {
132 timer = timer_queue.timer_next->timer_delta;
133 delta = ngx_msec();
134
135 } else {
136 timer = INFTIM;
137 delta = 0;
138 }
139
140 #if 1
141 /* DEBUG */
142 for (i = 0; i < nevents; i++) {
143 ngx_log_debug(log, "poll: %d, %d" _
144 event_list[i].fd _ event_list[i].events);
145 }
146 #endif
147
148 ngx_log_debug(log, "poll timer: %d" _ timer);
149
150 if ((ready = poll(event_list, nevents, timer)) == -1) {
151 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "poll() failed");
152 return NGX_ERROR;
153 }
154
155 ngx_log_debug(log, "poll ready %d" _ ready);
156
157 if (timer != INFTIM) {
158 delta = ngx_msec() - delta;
159
160 } else {
161 ngx_assert((ready != 0), return NGX_ERROR, log,
162 "poll() returns no events without timeout");
163 }
164
165 ngx_log_debug(log, "poll timer: %d, delta: %d" _ timer _ delta);
166
167 if (timer != INFTIM) {
168 if (delta >= timer) {
169 for ( ;; ) {
170 ev = timer_queue.timer_next;
171
172 if (ev == &timer_queue || delta < ev->timer_delta) {
173 break;
174 }
175
176 delta -= ev->timer_delta;
177 ngx_del_timer(ev);
178 ev->timedout = 1;
179
180 if (ev->event_handler(ev) == NGX_ERROR) {
181 ev->close_handler(ev);
182 }
183 }
184
185 } else {
186 timer_queue.timer_next->timer_delta -= delta;
187 }
188 }
189
190 for (i = 0; ready; i++) {
191 c = &ngx_connections[event_list[i].fd];
192
193 ngx_log_debug(log, "poll: fd:%d, ev:%d, rev:%d" _
194 event_list[i].fd _
195 event_list[i].events _ event_list[i].revents);
196
197 found = 0;
198
199 if (event_list[i].revents & POLLIN) {
200 found = 1;
201 c->read->ready = 1;
202
203 if (c->read->oneshot) {
204 ngx_del_timer(c->read);
205 ngx_select_del_event(c->read, NGX_READ_EVENT, 0);
206 }
207
208 if (c->read->event_handler(c->read) == NGX_ERROR) {
209 c->read->close_handler(c->read);
210 }
211 }
212
213 if (event_list[i].revents & POLLOUT) {
214 found = 1;
215 c->write->ready = 1;
216
217 if (c->write->oneshot) {
218 ngx_del_timer(c->write);
219 ngx_select_del_event(c->write, NGX_WRITE_EVENT, 0);
220 }
221
222 if (c->write->event_handler(c->write) == NGX_ERROR) {
223 c->write->close_handler(c->write);
224 }
225 }
226
227 if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
228 found = 1;
229 ngx_log_error(NGX_LOG_ERR, log, ngx_errno,
230 "poll() error on %d:%d",
231 event_list[i].fd, event_list[i].revents);
232 }
233
234 if (found) {
235 ready--;
236 }
237 }
238
239 return NGX_OK;
240 }
241
242 void ngx_poll_add_timer(ngx_event_t *ev, ngx_msec_t timer)
243 {
244 ngx_event_t *e;
245
246 for (e = timer_queue.timer_next;
247 e != &timer_queue && timer > e->timer_delta;
248 e = e->timer_next)
249 timer -= e->timer_delta;
250
251 ev->timer_delta = timer;
252
253 ev->timer_next = e;
254 ev->timer_prev = e->timer_prev;
255
256 e->timer_prev->timer_next = ev;
257 e->timer_prev = ev;
258 }