diff options
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r-- | src/daemon/daemon.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index 3caade12..0c198454 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -163,20 +163,35 @@ MHD_handle_connection (void *data) | |||
163 | fd_set ws; | 163 | fd_set ws; |
164 | fd_set es; | 164 | fd_set es; |
165 | int max; | 165 | int max; |
166 | struct timeval tv; | ||
167 | unsigned int timeout; | ||
168 | time_t now; | ||
166 | 169 | ||
167 | if (con == NULL) | 170 | if (con == NULL) |
168 | abort (); | 171 | abort (); |
169 | while ((!con->daemon->shutdown) && (con->socket_fd != -1)) | 172 | timeout = con->daemon->connection_timeout; |
173 | now = time(NULL); | ||
174 | while ( (!con->daemon->shutdown) && | ||
175 | (con->socket_fd != -1) && | ||
176 | ( (timeout == 0) || | ||
177 | (now - timeout > con->last_activity) ) ) | ||
170 | { | 178 | { |
171 | FD_ZERO (&rs); | 179 | FD_ZERO (&rs); |
172 | FD_ZERO (&ws); | 180 | FD_ZERO (&ws); |
173 | FD_ZERO (&es); | 181 | FD_ZERO (&es); |
174 | max = 0; | 182 | max = 0; |
175 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); | 183 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); |
176 | num_ready = SELECT (max + 1, &rs, &ws, &es, NULL); | 184 | tv.tv_usec = 0; |
177 | if (num_ready <= 0) | 185 | tv.tv_sec = timeout - (now - con->last_activity); |
186 | num_ready = SELECT (max + 1, | ||
187 | &rs, | ||
188 | &ws, | ||
189 | &es, | ||
190 | (tv.tv_sec != 0) ? &tv : NULL); | ||
191 | now = time(NULL); | ||
192 | if (num_ready < 0) | ||
178 | { | 193 | { |
179 | if (errno == EINTR) | 194 | if (errno == EINTR) |
180 | continue; | 195 | continue; |
181 | break; | 196 | break; |
182 | } | 197 | } |
@@ -188,6 +203,10 @@ MHD_handle_connection (void *data) | |||
188 | break; | 203 | break; |
189 | if ((con->headersReceived == 1) && (con->response == NULL)) | 204 | if ((con->headersReceived == 1) && (con->response == NULL)) |
190 | MHD_call_connection_handler (con); | 205 | MHD_call_connection_handler (con); |
206 | if ( (con->socket_fd != -1) && | ||
207 | ( (FD_ISSET (con->socket_fd, &rs)) || | ||
208 | (FD_ISSET (con->socket_fd, &ws)) ) ) | ||
209 | con->last_activity = now; | ||
191 | } | 210 | } |
192 | if (con->socket_fd != -1) | 211 | if (con->socket_fd != -1) |
193 | { | 212 | { |
@@ -261,6 +280,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
261 | free (connection); | 280 | free (connection); |
262 | return MHD_NO; | 281 | return MHD_NO; |
263 | } | 282 | } |
283 | connection->last_activity = time(NULL); | ||
264 | connection->next = daemon->connections; | 284 | connection->next = daemon->connections; |
265 | daemon->connections = connection; | 285 | daemon->connections = connection; |
266 | daemon->max_connections--; | 286 | daemon->max_connections--; |
@@ -284,11 +304,22 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
284 | struct MHD_Connection *pos; | 304 | struct MHD_Connection *pos; |
285 | struct MHD_Connection *prev; | 305 | struct MHD_Connection *prev; |
286 | void *unused; | 306 | void *unused; |
307 | time_t timeout; | ||
287 | 308 | ||
309 | timeout = time(NULL); | ||
310 | if (daemon->connection_timeout != 0) | ||
311 | timeout -= daemon->connection_timeout; | ||
312 | else | ||
313 | timeout = 0; | ||
288 | pos = daemon->connections; | 314 | pos = daemon->connections; |
289 | prev = NULL; | 315 | prev = NULL; |
290 | while (pos != NULL) | 316 | while (pos != NULL) |
291 | { | 317 | { |
318 | if ( (pos->last_activity < timeout) && | ||
319 | (pos->socket_fd != -1) ) { | ||
320 | CLOSE(pos->socket_fd); | ||
321 | pos->socket_fd = -1; | ||
322 | } | ||
292 | if (pos->socket_fd == -1) | 323 | if (pos->socket_fd == -1) |
293 | { | 324 | { |
294 | if (prev == NULL) | 325 | if (prev == NULL) |
@@ -339,6 +370,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) | |||
339 | int max; | 370 | int max; |
340 | struct timeval timeout; | 371 | struct timeval timeout; |
341 | int ds; | 372 | int ds; |
373 | time_t now; | ||
342 | 374 | ||
343 | timeout.tv_sec = 0; | 375 | timeout.tv_sec = 0; |
344 | timeout.tv_usec = 0; | 376 | timeout.tv_usec = 0; |
@@ -378,6 +410,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) | |||
378 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 410 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
379 | { | 411 | { |
380 | /* do not have a thread per connection, process all connections now */ | 412 | /* do not have a thread per connection, process all connections now */ |
413 | now = time(NULL); | ||
381 | pos = daemon->connections; | 414 | pos = daemon->connections; |
382 | while (pos != NULL) | 415 | while (pos != NULL) |
383 | { | 416 | { |
@@ -387,10 +420,14 @@ MHD_select (struct MHD_Daemon *daemon, int may_block) | |||
387 | pos = pos->next; | 420 | pos = pos->next; |
388 | continue; | 421 | continue; |
389 | } | 422 | } |
390 | if (FD_ISSET (ds, &rs)) | 423 | if (FD_ISSET (ds, &rs)) { |
424 | pos->last_activity = now; | ||
391 | MHD_connection_handle_read (pos); | 425 | MHD_connection_handle_read (pos); |
392 | if (FD_ISSET (ds, &ws)) | 426 | } |
427 | if (FD_ISSET (ds, &ws)) { | ||
428 | pos->last_activity = now; | ||
393 | MHD_connection_handle_write (pos); | 429 | MHD_connection_handle_write (pos); |
430 | } | ||
394 | pos = pos->next; | 431 | pos = pos->next; |
395 | } | 432 | } |
396 | } | 433 | } |
@@ -530,6 +567,7 @@ MHD_start_daemon (unsigned int options, | |||
530 | retVal->default_handler.next = NULL; | 567 | retVal->default_handler.next = NULL; |
531 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; | 568 | retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; |
532 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; | 569 | retVal->pool_size = MHD_POOL_SIZE_DEFAULT; |
570 | retVal->connection_timeout = 0; /* no timeout */ | ||
533 | va_start (ap, dh_cls); | 571 | va_start (ap, dh_cls); |
534 | while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) | 572 | while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) |
535 | { | 573 | { |
@@ -541,6 +579,9 @@ MHD_start_daemon (unsigned int options, | |||
541 | case MHD_OPTION_CONNECTION_LIMIT: | 579 | case MHD_OPTION_CONNECTION_LIMIT: |
542 | retVal->max_connections = va_arg (ap, unsigned int); | 580 | retVal->max_connections = va_arg (ap, unsigned int); |
543 | break; | 581 | break; |
582 | case MHD_OPTION_CONNECTION_TIMEOUT: | ||
583 | retVal->connection_timeout = va_arg (ap, unsigned int); | ||
584 | break; | ||
544 | default: | 585 | default: |
545 | fprintf (stderr, | 586 | fprintf (stderr, |
546 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); | 587 | "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); |