aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_epoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_epoll.c')
-rw-r--r--src/lib/daemon_epoll.c533
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 */
55static bool 55static bool
56is_urh_ready (struct MHD_UpgradeResponseHandle * const urh) 56is_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 */
213enum MHD_StatusCode 213enum MHD_StatusCode
214MHD_daemon_epoll_ (struct MHD_Daemon *daemon, 214MHD_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