diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 7e13e311..77f43537 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -1281,6 +1281,17 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1281 | 1281 | ||
1282 | 1282 | ||
1283 | /** | 1283 | /** |
1284 | * Free resources associated with all closed connections. | ||
1285 | * (destroy responses, free buffers, etc.). All closed | ||
1286 | * connections are kept in the "cleanup" doubly-linked list. | ||
1287 | * | ||
1288 | * @param daemon daemon to clean up | ||
1289 | */ | ||
1290 | static void | ||
1291 | MHD_cleanup_connections (struct MHD_Daemon *daemon); | ||
1292 | |||
1293 | |||
1294 | /** | ||
1284 | * Add another client connection to the set of connections | 1295 | * Add another client connection to the set of connections |
1285 | * managed by MHD. This API is usually not needed (since | 1296 | * managed by MHD. This API is usually not needed (since |
1286 | * MHD will accept inbound connections on the server socket). | 1297 | * MHD will accept inbound connections on the server socket). |
@@ -1371,6 +1382,8 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1371 | client_socket); | 1382 | client_socket); |
1372 | #endif | 1383 | #endif |
1373 | #endif | 1384 | #endif |
1385 | //if (daemon->connections == daemon->connection_limit) | ||
1386 | // MHD_cleanup_connections (daemon); /* try to aggressively clean up to make room */ | ||
1374 | if ( (daemon->connections == daemon->connection_limit) || | 1387 | if ( (daemon->connections == daemon->connection_limit) || |
1375 | (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) ) | 1388 | (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) ) |
1376 | { | 1389 | { |
@@ -1537,7 +1550,7 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1537 | 1550 | ||
1538 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 1551 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
1539 | { | 1552 | { |
1540 | if (!MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) | 1553 | if (! MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) |
1541 | MHD_PANIC ("Failed to acquire cleanup mutex\n"); | 1554 | MHD_PANIC ("Failed to acquire cleanup mutex\n"); |
1542 | } | 1555 | } |
1543 | else | 1556 | else |
@@ -2070,7 +2083,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2070 | struct MHD_Connection *pos; | 2083 | struct MHD_Connection *pos; |
2071 | 2084 | ||
2072 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2085 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2073 | (!MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) | 2086 | (! MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) |
2074 | MHD_PANIC ("Failed to acquire cleanup mutex\n"); | 2087 | MHD_PANIC ("Failed to acquire cleanup mutex\n"); |
2075 | while (NULL != (pos = daemon->cleanup_head)) | 2088 | while (NULL != (pos = daemon->cleanup_head)) |
2076 | { | 2089 | { |
@@ -2080,7 +2093,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2080 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2093 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2081 | (MHD_NO == pos->thread_joined) ) | 2094 | (MHD_NO == pos->thread_joined) ) |
2082 | { | 2095 | { |
2083 | if (!MHD_join_thread_ (pos->pid)) | 2096 | if (! MHD_join_thread_ (pos->pid)) |
2084 | { | 2097 | { |
2085 | MHD_PANIC ("Failed to join a thread\n"); | 2098 | MHD_PANIC ("Failed to join a thread\n"); |
2086 | } | 2099 | } |
@@ -2092,6 +2105,8 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2092 | #endif | 2105 | #endif |
2093 | daemon->connections--; | 2106 | daemon->connections--; |
2094 | daemon->at_limit = MHD_NO; | 2107 | daemon->at_limit = MHD_NO; |
2108 | |||
2109 | /* clean up the connection */ | ||
2095 | if (NULL != daemon->notify_connection) | 2110 | if (NULL != daemon->notify_connection) |
2096 | daemon->notify_connection (daemon->notify_connection_cls, | 2111 | daemon->notify_connection (daemon->notify_connection_cls, |
2097 | pos, | 2112 | pos, |
@@ -2141,7 +2156,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2141 | free (pos); | 2156 | free (pos); |
2142 | } | 2157 | } |
2143 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2158 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2144 | (!MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) | 2159 | (! MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) |
2145 | MHD_PANIC ("Failed to release cleanup mutex\n"); | 2160 | MHD_PANIC ("Failed to release cleanup mutex\n"); |
2146 | } | 2161 | } |
2147 | 2162 | ||
@@ -2364,17 +2379,6 @@ MHD_select (struct MHD_Daemon *daemon, | |||
2364 | #endif | 2379 | #endif |
2365 | err_state = MHD_YES; | 2380 | err_state = MHD_YES; |
2366 | } | 2381 | } |
2367 | |||
2368 | /* If we're at the connection limit, no need to | ||
2369 | accept new connections; however, make sure | ||
2370 | we do not miss the shutdown, so only do this | ||
2371 | optimization if we have a shutdown signaling | ||
2372 | pipe. */ | ||
2373 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | ||
2374 | ( ( (daemon->connections == daemon->connection_limit) && | ||
2375 | (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) ) || | ||
2376 | (MHD_YES == daemon->at_limit) ) ) | ||
2377 | FD_CLR (daemon->socket_fd, &rs); | ||
2378 | } | 2382 | } |
2379 | else | 2383 | else |
2380 | { | 2384 | { |
@@ -2420,7 +2424,21 @@ MHD_select (struct MHD_Daemon *daemon, | |||
2420 | } | 2424 | } |
2421 | #endif /* MHD_WINSOCK_SOCKETS */ | 2425 | #endif /* MHD_WINSOCK_SOCKETS */ |
2422 | } | 2426 | } |
2423 | 2427 | /* Stop listening if we are at the configured connection limit */ | |
2428 | /* If we're at the connection limit, no point in really | ||
2429 | accepting new connections; however, make sure we do not miss | ||
2430 | the shutdown OR the termination of an existing connection; so | ||
2431 | only do this optimization if we have a signaling pipe in | ||
2432 | place. */ | ||
2433 | if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && | ||
2434 | (MHD_INVALID_PIPE_ != daemon->wpipe[0]) && | ||
2435 | (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) && | ||
2436 | ( (daemon->connections == daemon->connection_limit) || | ||
2437 | (MHD_YES == daemon->at_limit) ) ) | ||
2438 | { | ||
2439 | FD_CLR (daemon->socket_fd, | ||
2440 | &rs); | ||
2441 | } | ||
2424 | tv = NULL; | 2442 | tv = NULL; |
2425 | if (MHD_YES == err_state) | 2443 | if (MHD_YES == err_state) |
2426 | may_block = MHD_NO; | 2444 | may_block = MHD_NO; |
@@ -4185,7 +4203,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
4185 | } | 4203 | } |
4186 | #endif | 4204 | #endif |
4187 | 4205 | ||
4188 | if (!MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) | 4206 | if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) |
4189 | { | 4207 | { |
4190 | #ifdef HAVE_MESSAGES | 4208 | #ifdef HAVE_MESSAGES |
4191 | MHD_DLOG (daemon, | 4209 | MHD_DLOG (daemon, |
@@ -4196,7 +4214,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
4196 | MHD_PANIC ("close failed\n"); | 4214 | MHD_PANIC ("close failed\n"); |
4197 | goto free_and_fail; | 4215 | goto free_and_fail; |
4198 | } | 4216 | } |
4199 | if (!MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) | 4217 | if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) |
4200 | { | 4218 | { |
4201 | #ifdef HAVE_MESSAGES | 4219 | #ifdef HAVE_MESSAGES |
4202 | MHD_DLOG (daemon, | 4220 | MHD_DLOG (daemon, |
@@ -4229,12 +4247,12 @@ MHD_start_daemon_va (unsigned int flags, | |||
4229 | ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && | 4247 | ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && |
4230 | (0 == daemon->worker_pool_size)) ) && | 4248 | (0 == daemon->worker_pool_size)) ) && |
4231 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && | 4249 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && |
4232 | (!MHD_create_named_thread_ (&daemon->pid, | 4250 | (! MHD_create_named_thread_ (&daemon->pid, |
4233 | (flags & MHD_USE_THREAD_PER_CONNECTION) ? | 4251 | (flags & MHD_USE_THREAD_PER_CONNECTION) ? |
4234 | "MHD-listen" : "MHD-single", | 4252 | "MHD-listen" : "MHD-single", |
4235 | daemon->thread_stack_size, | 4253 | daemon->thread_stack_size, |
4236 | &MHD_select_thread, | 4254 | &MHD_select_thread, |
4237 | daemon) ) ) | 4255 | daemon) ) ) |
4238 | { | 4256 | { |
4239 | #ifdef HAVE_MESSAGES | 4257 | #ifdef HAVE_MESSAGES |
4240 | MHD_DLOG (daemon, | 4258 | MHD_DLOG (daemon, |
@@ -4342,11 +4360,11 @@ MHD_start_daemon_va (unsigned int flags, | |||
4342 | } | 4360 | } |
4343 | 4361 | ||
4344 | /* Spawn the worker thread */ | 4362 | /* Spawn the worker thread */ |
4345 | if (!MHD_create_named_thread_(&d->pid, | 4363 | if (! MHD_create_named_thread_(&d->pid, |
4346 | "MHD-worker", | 4364 | "MHD-worker", |
4347 | daemon->thread_stack_size, | 4365 | daemon->thread_stack_size, |
4348 | &MHD_select_thread, | 4366 | &MHD_select_thread, |
4349 | d)) | 4367 | d)) |
4350 | { | 4368 | { |
4351 | #ifdef HAVE_MESSAGES | 4369 | #ifdef HAVE_MESSAGES |
4352 | MHD_DLOG (daemon, | 4370 | MHD_DLOG (daemon, |