diff options
Diffstat (limited to 'src/lib/daemon_epoll.c')
-rw-r--r-- | src/lib/daemon_epoll.c | 533 |
1 files changed, 269 insertions, 264 deletions
diff --git a/src/lib/daemon_epoll.c b/src/lib/daemon_epoll.c index 4bed148f..b25ba9a7 100644 --- a/src/lib/daemon_epoll.c +++ b/src/lib/daemon_epoll.c | |||
@@ -53,9 +53,9 @@ | |||
53 | * 'false' otherwise | 53 | * 'false' otherwise |
54 | */ | 54 | */ |
55 | static bool | 55 | static bool |
56 | is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) | 56 | is_urh_ready (struct MHD_UpgradeResponseHandle *const urh) |
57 | { | 57 | { |
58 | const struct MHD_Connection * const connection = urh->connection; | 58 | const struct MHD_Connection *const connection = urh->connection; |
59 | 59 | ||
60 | if ( (0 == urh->in_buffer_size) && | 60 | if ( (0 == urh->in_buffer_size) && |
61 | (0 == urh->out_buffer_size) && | 61 | (0 == urh->out_buffer_size) && |
@@ -80,7 +80,7 @@ is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) | |||
80 | return true; | 80 | return true; |
81 | 81 | ||
82 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 82 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
83 | (urh->in_buffer_used > 0) ) | 83 | (urh->in_buffer_used > 0) ) |
84 | return true; | 84 | return true; |
85 | 85 | ||
86 | return false; | 86 | return false; |
@@ -103,99 +103,99 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
103 | { | 103 | { |
104 | struct epoll_event events[MAX_EVENTS]; | 104 | struct epoll_event events[MAX_EVENTS]; |
105 | int num_events; | 105 | int num_events; |
106 | struct MHD_UpgradeResponseHandle * pos; | 106 | struct MHD_UpgradeResponseHandle *pos; |
107 | struct MHD_UpgradeResponseHandle * prev; | 107 | struct MHD_UpgradeResponseHandle *prev; |
108 | 108 | ||
109 | num_events = MAX_EVENTS; | 109 | num_events = MAX_EVENTS; |
110 | while (MAX_EVENTS == num_events) | 110 | while (MAX_EVENTS == num_events) |
111 | { | ||
112 | unsigned int i; | ||
113 | |||
114 | /* update event masks */ | ||
115 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
116 | events, | ||
117 | MAX_EVENTS, | ||
118 | 0); | ||
119 | if (-1 == num_events) | ||
111 | { | 120 | { |
112 | unsigned int i; | 121 | const int err = MHD_socket_get_error_ (); |
113 | 122 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | |
114 | /* update event masks */ | 123 | return MHD_SC_OK; |
115 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
116 | events, | ||
117 | MAX_EVENTS, | ||
118 | 0); | ||
119 | if (-1 == num_events) | ||
120 | { | ||
121 | const int err = MHD_socket_get_error_ (); | ||
122 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
123 | return MHD_SC_OK; | ||
124 | #ifdef HAVE_MESSAGES | 124 | #ifdef HAVE_MESSAGES |
125 | MHD_DLOG (daemon, | 125 | MHD_DLOG (daemon, |
126 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, | 126 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, |
127 | _("Call to epoll_wait failed: %s\n"), | 127 | _ ("Call to epoll_wait failed: %s\n"), |
128 | MHD_socket_strerr_ (err)); | 128 | MHD_socket_strerr_ (err)); |
129 | #endif | 129 | #endif |
130 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; | 130 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; |
131 | } | 131 | } |
132 | for (i = 0; i < (unsigned int) num_events; i++) | 132 | for (i = 0; i < (unsigned int) num_events; i++) |
133 | { | 133 | { |
134 | struct UpgradeEpollHandle * const ueh = events[i].data.ptr; | 134 | struct UpgradeEpollHandle *const ueh = events[i].data.ptr; |
135 | struct MHD_UpgradeResponseHandle * const urh = ueh->urh; | 135 | struct MHD_UpgradeResponseHandle *const urh = ueh->urh; |
136 | bool new_err_state = false; | 136 | bool new_err_state = false; |
137 | 137 | ||
138 | if (urh->clean_ready) | 138 | if (urh->clean_ready) |
139 | continue; | 139 | continue; |
140 | 140 | ||
141 | /* Update ueh state based on what is ready according to epoll() */ | 141 | /* Update ueh state based on what is ready according to epoll() */ |
142 | if (0 != (events[i].events & EPOLLIN)) | 142 | if (0 != (events[i].events & EPOLLIN)) |
143 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; | 143 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; |
144 | if (0 != (events[i].events & EPOLLOUT)) | 144 | if (0 != (events[i].events & EPOLLOUT)) |
145 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; | 145 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; |
146 | if (0 != (events[i].events & EPOLLHUP)) | 146 | if (0 != (events[i].events & EPOLLHUP)) |
147 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 147 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; |
148 | 148 | ||
149 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && | 149 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && |
150 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) | 150 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) |
151 | { | 151 | { |
152 | /* Process new error state only one time | 152 | /* Process new error state only one time |
153 | * and avoid continuously marking this connection | 153 | * and avoid continuously marking this connection |
154 | * as 'ready'. */ | 154 | * as 'ready'. */ |
155 | ueh->celi |= MHD_EPOLL_STATE_ERROR; | 155 | ueh->celi |= MHD_EPOLL_STATE_ERROR; |
156 | new_err_state = true; | 156 | new_err_state = true; |
157 | } | 157 | } |
158 | 158 | ||
159 | if (! urh->in_eready_list) | 159 | if (! urh->in_eready_list) |
160 | { | 160 | { |
161 | if (new_err_state || | 161 | if (new_err_state || |
162 | is_urh_ready(urh)) | 162 | is_urh_ready (urh)) |
163 | { | 163 | { |
164 | EDLL_insert (daemon->eready_urh_head, | 164 | EDLL_insert (daemon->eready_urh_head, |
165 | daemon->eready_urh_tail, | 165 | daemon->eready_urh_tail, |
166 | urh); | 166 | urh); |
167 | urh->in_eready_list = true; | 167 | urh->in_eready_list = true; |
168 | } | ||
169 | } | ||
170 | } | 168 | } |
169 | } | ||
171 | } | 170 | } |
171 | } | ||
172 | prev = daemon->eready_urh_tail; | 172 | prev = daemon->eready_urh_tail; |
173 | while (NULL != (pos = prev)) | 173 | while (NULL != (pos = prev)) |
174 | { | ||
175 | prev = pos->prevE; | ||
176 | MHD_upgrade_response_handle_process_ (pos); | ||
177 | if (! is_urh_ready (pos)) | ||
174 | { | 178 | { |
175 | prev = pos->prevE; | 179 | EDLL_remove (daemon->eready_urh_head, |
176 | MHD_upgrade_response_handle_process_ (pos); | 180 | daemon->eready_urh_tail, |
177 | if (! is_urh_ready(pos)) | 181 | pos); |
178 | { | 182 | pos->in_eready_list = false; |
179 | EDLL_remove (daemon->eready_urh_head, | 183 | } |
180 | daemon->eready_urh_tail, | 184 | /* Finished forwarding? */ |
181 | pos); | 185 | if ( (0 == pos->in_buffer_size) && |
182 | pos->in_eready_list = false; | 186 | (0 == pos->out_buffer_size) && |
183 | } | 187 | (0 == pos->in_buffer_used) && |
184 | /* Finished forwarding? */ | 188 | (0 == pos->out_buffer_used) ) |
185 | if ( (0 == pos->in_buffer_size) && | 189 | { |
186 | (0 == pos->out_buffer_size) && | 190 | MHD_connection_finish_forward_ (pos->connection); |
187 | (0 == pos->in_buffer_used) && | 191 | pos->clean_ready = true; |
188 | (0 == pos->out_buffer_used) ) | 192 | /* If 'pos->was_closed' already was set to true, connection |
189 | { | 193 | * will be moved immediately to cleanup list. Otherwise |
190 | MHD_connection_finish_forward_ (pos->connection); | 194 | * connection will stay in suspended list until 'pos' will |
191 | pos->clean_ready = true; | 195 | * be marked with 'was_closed' by application. */ |
192 | /* If 'pos->was_closed' already was set to true, connection | 196 | MHD_request_resume (&pos->connection->request); |
193 | * will be moved immediately to cleanup list. Otherwise | ||
194 | * connection will stay in suspended list until 'pos' will | ||
195 | * be marked with 'was_closed' by application. */ | ||
196 | MHD_request_resume (&pos->connection->request); | ||
197 | } | ||
198 | } | 197 | } |
198 | } | ||
199 | 199 | ||
200 | return MHD_SC_OK; | 200 | return MHD_SC_OK; |
201 | } | 201 | } |
@@ -212,10 +212,10 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
212 | */ | 212 | */ |
213 | enum MHD_StatusCode | 213 | enum MHD_StatusCode |
214 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | 214 | MHD_daemon_epoll_ (struct MHD_Daemon *daemon, |
215 | bool may_block) | 215 | bool may_block) |
216 | { | 216 | { |
217 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 217 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
218 | static const char * const upgrade_marker = "upgrade_ptr"; | 218 | static const char *const upgrade_marker = "upgrade_ptr"; |
219 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 219 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
220 | struct MHD_Connection *pos; | 220 | struct MHD_Connection *pos; |
221 | struct MHD_Connection *prev; | 221 | struct MHD_Connection *prev; |
@@ -239,24 +239,24 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
239 | (daemon->connections < daemon->global_connection_limit) && | 239 | (daemon->connections < daemon->global_connection_limit) && |
240 | (! daemon->listen_socket_in_epoll) && | 240 | (! daemon->listen_socket_in_epoll) && |
241 | (! daemon->at_limit) ) | 241 | (! daemon->at_limit) ) |
242 | { | ||
243 | event.events = EPOLLIN; | ||
244 | event.data.ptr = daemon; | ||
245 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
246 | EPOLL_CTL_ADD, | ||
247 | ls, | ||
248 | &event)) | ||
242 | { | 249 | { |
243 | event.events = EPOLLIN; | ||
244 | event.data.ptr = daemon; | ||
245 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
246 | EPOLL_CTL_ADD, | ||
247 | ls, | ||
248 | &event)) | ||
249 | { | ||
250 | #ifdef HAVE_MESSAGES | 250 | #ifdef HAVE_MESSAGES |
251 | MHD_DLOG (daemon, | 251 | MHD_DLOG (daemon, |
252 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 252 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
253 | _("Call to epoll_ctl failed: %s\n"), | 253 | _ ("Call to epoll_ctl failed: %s\n"), |
254 | MHD_socket_last_strerr_ ()); | 254 | MHD_socket_last_strerr_ ()); |
255 | #endif | 255 | #endif |
256 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 256 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
257 | } | ||
258 | daemon->listen_socket_in_epoll = true; | ||
259 | } | 257 | } |
258 | daemon->listen_socket_in_epoll = true; | ||
259 | } | ||
260 | if ( (daemon->was_quiesced) && | 260 | if ( (daemon->was_quiesced) && |
261 | (daemon->listen_socket_in_epoll) ) | 261 | (daemon->listen_socket_in_epoll) ) |
262 | { | 262 | { |
@@ -271,58 +271,58 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
271 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 271 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
272 | if ( (! daemon->upgrade_fd_in_epoll) && | 272 | if ( (! daemon->upgrade_fd_in_epoll) && |
273 | (-1 != daemon->epoll_upgrade_fd) ) | 273 | (-1 != daemon->epoll_upgrade_fd) ) |
274 | { | ||
275 | event.events = EPOLLIN | EPOLLOUT; | ||
276 | event.data.ptr = (void *) upgrade_marker; | ||
277 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
278 | EPOLL_CTL_ADD, | ||
279 | daemon->epoll_upgrade_fd, | ||
280 | &event)) | ||
274 | { | 281 | { |
275 | event.events = EPOLLIN | EPOLLOUT; | ||
276 | event.data.ptr = (void *) upgrade_marker; | ||
277 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
278 | EPOLL_CTL_ADD, | ||
279 | daemon->epoll_upgrade_fd, | ||
280 | &event)) | ||
281 | { | ||
282 | #ifdef HAVE_MESSAGES | 282 | #ifdef HAVE_MESSAGES |
283 | MHD_DLOG (daemon, | 283 | MHD_DLOG (daemon, |
284 | MHD_SC_EPOLL_CTL_ADD_FAILED, | 284 | MHD_SC_EPOLL_CTL_ADD_FAILED, |
285 | _("Call to epoll_ctl failed: %s\n"), | 285 | _ ("Call to epoll_ctl failed: %s\n"), |
286 | MHD_socket_last_strerr_ ()); | 286 | MHD_socket_last_strerr_ ()); |
287 | #endif | 287 | #endif |
288 | return MHD_SC_EPOLL_CTL_ADD_FAILED; | 288 | return MHD_SC_EPOLL_CTL_ADD_FAILED; |
289 | } | ||
290 | daemon->upgrade_fd_in_epoll = true; | ||
291 | } | 289 | } |
290 | daemon->upgrade_fd_in_epoll = true; | ||
291 | } | ||
292 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 292 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
293 | if ( (daemon->listen_socket_in_epoll) && | 293 | if ( (daemon->listen_socket_in_epoll) && |
294 | ( (daemon->connections == daemon->global_connection_limit) || | 294 | ( (daemon->connections == daemon->global_connection_limit) || |
295 | (daemon->at_limit) || | 295 | (daemon->at_limit) || |
296 | (daemon->was_quiesced) ) ) | 296 | (daemon->was_quiesced) ) ) |
297 | { | 297 | { |
298 | /* we're at the connection limit, disable listen socket | 298 | /* we're at the connection limit, disable listen socket |
299 | for event loop for now */ | 299 | for event loop for now */ |
300 | if (0 != epoll_ctl (daemon->epoll_fd, | 300 | if (0 != epoll_ctl (daemon->epoll_fd, |
301 | EPOLL_CTL_DEL, | 301 | EPOLL_CTL_DEL, |
302 | ls, | 302 | ls, |
303 | NULL)) | 303 | NULL)) |
304 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | 304 | MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n")); |
305 | daemon->listen_socket_in_epoll = false; | 305 | daemon->listen_socket_in_epoll = false; |
306 | } | 306 | } |
307 | 307 | ||
308 | if ( (! daemon->disallow_suspend_resume) && | 308 | if ( (! daemon->disallow_suspend_resume) && |
309 | (MHD_resume_suspended_connections_ (daemon)) ) | 309 | (MHD_resume_suspended_connections_ (daemon)) ) |
310 | may_block = false; | 310 | may_block = false; |
311 | 311 | ||
312 | if (may_block) | 312 | if (may_block) |
313 | { | ||
314 | if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */ | ||
315 | MHD_daemon_get_timeout (daemon, | ||
316 | &timeout_ll)) | ||
313 | { | 317 | { |
314 | if (MHD_SC_OK == /* FIXME: distinguish between NO_TIMEOUT and errors */ | 318 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) |
315 | MHD_daemon_get_timeout (daemon, | 319 | timeout_ms = INT_MAX; |
316 | &timeout_ll)) | ||
317 | { | ||
318 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) | ||
319 | timeout_ms = INT_MAX; | ||
320 | else | ||
321 | timeout_ms = (int) timeout_ll; | ||
322 | } | ||
323 | else | 320 | else |
324 | timeout_ms = -1; | 321 | timeout_ms = (int) timeout_ll; |
325 | } | 322 | } |
323 | else | ||
324 | timeout_ms = -1; | ||
325 | } | ||
326 | else | 326 | else |
327 | timeout_ms = 0; | 327 | timeout_ms = 0; |
328 | 328 | ||
@@ -337,113 +337,114 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
337 | than unfair behavior... */ | 337 | than unfair behavior... */ |
338 | num_events = MAX_EVENTS; | 338 | num_events = MAX_EVENTS; |
339 | while (MAX_EVENTS == num_events) | 339 | while (MAX_EVENTS == num_events) |
340 | { | ||
341 | /* update event masks */ | ||
342 | num_events = epoll_wait (daemon->epoll_fd, | ||
343 | events, | ||
344 | MAX_EVENTS, | ||
345 | timeout_ms); | ||
346 | if (-1 == num_events) | ||
340 | { | 347 | { |
341 | /* update event masks */ | 348 | const int err = MHD_socket_get_error_ (); |
342 | num_events = epoll_wait (daemon->epoll_fd, | 349 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
343 | events, | 350 | return MHD_SC_OK; |
344 | MAX_EVENTS, | ||
345 | timeout_ms); | ||
346 | if (-1 == num_events) | ||
347 | { | ||
348 | const int err = MHD_socket_get_error_ (); | ||
349 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
350 | return MHD_SC_OK; | ||
351 | #ifdef HAVE_MESSAGES | 351 | #ifdef HAVE_MESSAGES |
352 | MHD_DLOG (daemon, | 352 | MHD_DLOG (daemon, |
353 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, | 353 | MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR, |
354 | _("Call to epoll_wait failed: %s\n"), | 354 | _ ("Call to epoll_wait failed: %s\n"), |
355 | MHD_socket_strerr_ (err)); | 355 | MHD_socket_strerr_ (err)); |
356 | #endif | 356 | #endif |
357 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; | 357 | return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR; |
358 | } | 358 | } |
359 | for (i=0;i<(unsigned int) num_events;i++) | 359 | for (i = 0; i<(unsigned int) num_events; i++) |
360 | { | 360 | { |
361 | /* First, check for the values of `ptr` that would indicate | 361 | /* First, check for the values of `ptr` that would indicate |
362 | that this event is not about a normal connection. */ | 362 | that this event is not about a normal connection. */ |
363 | if (NULL == events[i].data.ptr) | 363 | if (NULL == events[i].data.ptr) |
364 | continue; /* shutdown signal! */ | 364 | continue; /* shutdown signal! */ |
365 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 365 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
366 | if (upgrade_marker == events[i].data.ptr) | 366 | if (upgrade_marker == events[i].data.ptr) |
367 | { | 367 | { |
368 | /* activity on an upgraded connection, we process | 368 | /* activity on an upgraded connection, we process |
369 | those in a separate epoll() */ | 369 | those in a separate epoll() */ |
370 | run_upgraded = true; | 370 | run_upgraded = true; |
371 | continue; | 371 | continue; |
372 | } | 372 | } |
373 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 373 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
374 | if (daemon->epoll_itc_marker == events[i].data.ptr) | 374 | if (daemon->epoll_itc_marker == events[i].data.ptr) |
375 | { | 375 | { |
376 | /* It's OK to clear ITC here as all external | 376 | /* It's OK to clear ITC here as all external |
377 | conditions will be processed later. */ | 377 | conditions will be processed later. */ |
378 | MHD_itc_clear_ (daemon->itc); | 378 | MHD_itc_clear_ (daemon->itc); |
379 | continue; | 379 | continue; |
380 | } | 380 | } |
381 | if (daemon == events[i].data.ptr) | 381 | if (daemon == events[i].data.ptr) |
382 | { | 382 | { |
383 | /* Check for error conditions on listen socket. */ | 383 | /* Check for error conditions on listen socket. */ |
384 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ | 384 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ |
385 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) | 385 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) |
386 | { | 386 | { |
387 | unsigned int series_length = 0; | 387 | unsigned int series_length = 0; |
388 | /* Run 'accept' until it fails or daemon at limit of connections. | 388 | /* Run 'accept' until it fails or daemon at limit of connections. |
389 | * Do not accept more then 10 connections at once. The rest will | 389 | * Do not accept more then 10 connections at once. The rest will |
390 | * be accepted on next turn (level trigger is used for listen | 390 | * be accepted on next turn (level trigger is used for listen |
391 | * socket). */ | 391 | * socket). */ |
392 | while ( (MHD_SC_OK == | 392 | while ( (MHD_SC_OK == |
393 | MHD_accept_connection_ (daemon)) && | 393 | MHD_accept_connection_ (daemon)) && |
394 | (series_length < 10) && | 394 | (series_length < 10) && |
395 | (daemon->connections < daemon->global_connection_limit) && | 395 | (daemon->connections < daemon->global_connection_limit) && |
396 | (! daemon->at_limit) ) | 396 | (! daemon->at_limit) ) |
397 | series_length++; | 397 | series_length++; |
398 | } | 398 | } |
399 | continue; | 399 | continue; |
400 | } | 400 | } |
401 | /* this is an event relating to a 'normal' connection, | 401 | /* this is an event relating to a 'normal' connection, |
402 | remember the event and if appropriate mark the | 402 | remember the event and if appropriate mark the |
403 | connection as 'eready'. */ | 403 | connection as 'eready'. */ |
404 | pos = events[i].data.ptr; | 404 | pos = events[i].data.ptr; |
405 | /* normal processing: update read/write data */ | 405 | /* normal processing: update read/write data */ |
406 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) | 406 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) |
407 | { | 407 | { |
408 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; | 408 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; |
409 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 409 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
410 | { | 410 | { |
411 | EDLL_insert (daemon->eready_head, | 411 | EDLL_insert (daemon->eready_head, |
412 | daemon->eready_tail, | 412 | daemon->eready_tail, |
413 | pos); | 413 | pos); |
414 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 414 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
415 | } | 415 | } |
416 | } | 416 | } |
417 | else | 417 | else |
418 | { | 418 | { |
419 | if (0 != (events[i].events & EPOLLIN)) | 419 | if (0 != (events[i].events & EPOLLIN)) |
420 | { | 420 | { |
421 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; | 421 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; |
422 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) || | 422 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) || |
423 | (pos->request.read_buffer_size > pos->request.read_buffer_offset) ) && | 423 | (pos->request.read_buffer_size > |
424 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | 424 | pos->request.read_buffer_offset) ) && |
425 | { | 425 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) |
426 | EDLL_insert (daemon->eready_head, | 426 | { |
427 | daemon->eready_tail, | 427 | EDLL_insert (daemon->eready_head, |
428 | pos); | 428 | daemon->eready_tail, |
429 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 429 | pos); |
430 | } | 430 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
431 | } | 431 | } |
432 | if (0 != (events[i].events & EPOLLOUT)) | 432 | } |
433 | { | 433 | if (0 != (events[i].events & EPOLLOUT)) |
434 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; | 434 | { |
435 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && | 435 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; |
436 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | 436 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && |
437 | { | 437 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) |
438 | EDLL_insert (daemon->eready_head, | 438 | { |
439 | daemon->eready_tail, | 439 | EDLL_insert (daemon->eready_head, |
440 | pos); | 440 | daemon->eready_tail, |
441 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | 441 | pos); |
442 | } | 442 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; |
443 | } | 443 | } |
444 | } | ||
445 | } | 444 | } |
445 | } | ||
446 | } | 446 | } |
447 | } | ||
447 | 448 | ||
448 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 449 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
449 | if (run_upgraded) | 450 | if (run_upgraded) |
@@ -453,28 +454,32 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
453 | /* process events for connections */ | 454 | /* process events for connections */ |
454 | prev = daemon->eready_tail; | 455 | prev = daemon->eready_tail; |
455 | while (NULL != (pos = prev)) | 456 | while (NULL != (pos = prev)) |
457 | { | ||
458 | prev = pos->prevE; | ||
459 | MHD_connection_call_handlers_ (pos, | ||
460 | 0 != (pos->epoll_state | ||
461 | & MHD_EPOLL_STATE_READ_READY), | ||
462 | 0 != (pos->epoll_state | ||
463 | & MHD_EPOLL_STATE_WRITE_READY), | ||
464 | 0 != (pos->epoll_state | ||
465 | & MHD_EPOLL_STATE_ERROR)); | ||
466 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == | ||
467 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | ||
468 | | MHD_EPOLL_STATE_IN_EREADY_EDLL))) | ||
456 | { | 469 | { |
457 | prev = pos->prevE; | 470 | if ( ((MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info) && |
458 | MHD_connection_call_handlers_ (pos, | 471 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) || |
459 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), | 472 | ((MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info) && |
460 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), | 473 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) || |
461 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); | 474 | (MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) ) |
462 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == | 475 | { |
463 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL))) | 476 | EDLL_remove (daemon->eready_head, |
464 | { | 477 | daemon->eready_tail, |
465 | if ( (MHD_EVENT_LOOP_INFO_READ == pos->request.event_loop_info && | 478 | pos); |
466 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) || | 479 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
467 | (MHD_EVENT_LOOP_INFO_WRITE == pos->request.event_loop_info && | 480 | } |
468 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) || | ||
469 | MHD_EVENT_LOOP_INFO_CLEANUP == pos->request.event_loop_info) | ||
470 | { | ||
471 | EDLL_remove (daemon->eready_head, | ||
472 | daemon->eready_tail, | ||
473 | pos); | ||
474 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
475 | } | ||
476 | } | ||
477 | } | 481 | } |
482 | } | ||
478 | 483 | ||
479 | /* Finally, handle timed-out connections; we need to do this here | 484 | /* Finally, handle timed-out connections; we need to do this here |
480 | as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything, | 485 | as the epoll mechanism won't call the 'MHD_request_handle_idle_()' on everything, |
@@ -486,22 +491,22 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon, | |||
486 | do not bother to sort that (presumably very short) list. */ | 491 | do not bother to sort that (presumably very short) list. */ |
487 | prev = daemon->manual_timeout_tail; | 492 | prev = daemon->manual_timeout_tail; |
488 | while (NULL != (pos = prev)) | 493 | while (NULL != (pos = prev)) |
489 | { | 494 | { |
490 | prev = pos->prevX; | 495 | prev = pos->prevX; |
491 | MHD_request_handle_idle_ (&pos->request); | 496 | MHD_request_handle_idle_ (&pos->request); |
492 | } | 497 | } |
493 | /* Connections with the default timeout are sorted by prepending | 498 | /* Connections with the default timeout are sorted by prepending |
494 | them to the head of the list whenever we touch the connection; | 499 | them to the head of the list whenever we touch the connection; |
495 | thus it suffices to iterate from the tail until the first | 500 | thus it suffices to iterate from the tail until the first |
496 | connection is NOT timed out */ | 501 | connection is NOT timed out */ |
497 | prev = daemon->normal_timeout_tail; | 502 | prev = daemon->normal_timeout_tail; |
498 | while (NULL != (pos = prev)) | 503 | while (NULL != (pos = prev)) |
499 | { | 504 | { |
500 | prev = pos->prevX; | 505 | prev = pos->prevX; |
501 | MHD_request_handle_idle_ (&pos->request); | 506 | MHD_request_handle_idle_ (&pos->request); |
502 | if (MHD_REQUEST_CLOSED != pos->request.state) | 507 | if (MHD_REQUEST_CLOSED != pos->request.state) |
503 | break; /* sorted by timeout, no need to visit the rest! */ | 508 | break; /* sorted by timeout, no need to visit the rest! */ |
504 | } | 509 | } |
505 | return MHD_SC_OK; | 510 | return MHD_SC_OK; |
506 | } | 511 | } |
507 | #endif | 512 | #endif |