commit 19cf5ce05e994a01845469f35d722bc831f7d06e
parent b60bb4f7422894dea02dbbf09842ce26858b01b4
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Mon, 29 Dec 2025 11:15:31 +0100
add new connection: moved check for the daemon limit earlier
Diffstat:
1 file changed, 125 insertions(+), 129 deletions(-)
diff --git a/src/mhd2/daemon_add_conn.c b/src/mhd2/daemon_add_conn.c
@@ -53,9 +53,13 @@
#include "mhd_sys_options.h"
-#include "mhd_assert.h"
#include "sys_bool_type.h"
#include "sys_base_types.h"
+
+#include "mhd_assert.h"
+#include "mhd_unreachable.h"
+#include "mhd_assume.h"
+
#include "sys_offsetof.h"
#include "sys_sockets_types.h"
#include "sys_sockets_headers.h"
@@ -355,7 +359,6 @@ new_connection_prepare_ (struct MHD_Daemon *restrict daemon,
}
free (c);
}
- mhd_socket_close (client_socket);
mhd_assert (MHD_SC_OK != ret);
return ret; /* Failure exit point */
}
@@ -395,119 +398,113 @@ new_connection_process_inner (struct MHD_Daemon *restrict daemon,
res = MHD_SC_POOL_MEM_ALLOC_FAILURE;
}
else
- { /* 'pool' creation succeed */
+ {
+ /* 'pool' creation succeed */
- if (daemon->conns.block_new)
- { /* Connections limit */
- mhd_LOG_MSG (daemon, MHD_SC_LIMIT_CONNECTIONS_REACHED, \
- "Server reached connection limit. " \
- "Closing inbound connection.");
- res = MHD_SC_LIMIT_CONNECTIONS_REACHED;
- }
- else
- { /* Have space for new connection */
- mhd_assert (daemon->conns.count < daemon->conns.cfg.count_limit);
- daemon->conns.count++;
- daemon->conns.block_new =
- (daemon->conns.count >= daemon->conns.cfg.count_limit);
- mhd_DLINKEDL_INS_LAST (&(daemon->conns), connection, all_conn);
+ mhd_assert (! daemon->conns.block_new);
+ mhd_assert (daemon->conns.count < daemon->conns.cfg.count_limit);
+
+ daemon->conns.count++;
+ daemon->conns.block_new =
+ (daemon->conns.count >= daemon->conns.cfg.count_limit);
+ mhd_DLINKEDL_INS_LAST (&(daemon->conns), connection, all_conn);
- mhd_conn_init_activity_timeout (connection,
- daemon->conns.cfg.timeout_milsec);
+ mhd_conn_init_activity_timeout (connection,
+ daemon->conns.cfg.timeout_milsec);
- connection_set_http_layer_init_state (connection);
- connection_set_initial_state (connection);
+ connection_set_http_layer_init_state (connection);
+ connection_set_initial_state (connection);
- notify_app_conn (daemon, connection, false);
+ notify_app_conn (daemon, connection, false);
#ifdef MHD_SUPPORT_THREADS
- if (mhd_DAEMON_TYPE_LISTEN_ONLY == daemon->threading.d_type)
+ if (mhd_DAEMON_TYPE_LISTEN_ONLY == daemon->threading.d_type)
+ {
+ mhd_assert ((mhd_POLL_TYPE_SELECT == daemon->events.poll_type) || \
+ (mhd_POLL_TYPE_POLL == daemon->events.poll_type));
+ if (! mhd_create_named_thread (&connection->tid,
+ "MHD-connection",
+ daemon->threading.cfg.stack_size,
+ &mhd_worker_connection,
+ connection))
{
- mhd_assert ((mhd_POLL_TYPE_SELECT == daemon->events.poll_type) || \
- (mhd_POLL_TYPE_POLL == daemon->events.poll_type));
- if (! mhd_create_named_thread (&connection->tid,
- "MHD-connection",
- daemon->threading.cfg.stack_size,
- &mhd_worker_connection,
- connection))
- {
#ifdef EAGAIN
- if (EAGAIN == errno)
- {
- mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED,
- "Failed to create a new thread because it would "
- "have exceeded the system limit on the number of "
- "threads or no system resources available.");
- res = MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED;
- }
- else
+ if (EAGAIN == errno)
+ {
+ mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED,
+ "Failed to create a new thread because it would "
+ "have exceeded the system limit on the number of "
+ "threads or no system resources available.");
+ res = MHD_SC_CONNECTION_THREAD_SYS_LIMITS_REACHED;
+ }
+ else
#endif /* EAGAIN */
- if (1)
- {
- mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE,
- "Failed to create a thread.");
- res = MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE;
- }
+ if (1)
+ {
+ mhd_LOG_MSG (daemon, MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE,
+ "Failed to create a thread.");
+ res = MHD_SC_CONNECTION_THREAD_LAUNCH_FAILURE;
}
- else /* New thread has been created successfully */
- return MHD_SC_OK; /* *** Function success exit point *** */
}
- else
+ else /* New thread has been created successfully */
+ return MHD_SC_OK; /* *** Function success exit point *** */
+ }
+ else
#else /* ! MHD_SUPPORT_THREADS */
- if (1)
+ if (1)
#endif /* ! MHD_SUPPORT_THREADS */
- { /* No 'thread-per-connection' */
+ { /* No 'thread-per-connection' */
#ifdef MHD_SUPPORT_THREADS
- connection->tid = daemon->threading.tid;
+ connection->tid = daemon->threading.tid;
#endif /* MHD_SUPPORT_THREADS */
#ifdef MHD_SUPPORT_EPOLL
- if (mhd_POLL_TYPE_EPOLL == daemon->events.poll_type)
+ if (mhd_POLL_TYPE_EPOLL == daemon->events.poll_type)
+ {
+ struct epoll_event event;
+
+ event.events = EPOLLIN | EPOLLOUT | EPOLLET;
+ event.data.ptr = connection;
+ if (0 != epoll_ctl (daemon->events.data.epoll.e_fd,
+ EPOLL_CTL_ADD,
+ connection->sk.fd,
+ &event))
{
- struct epoll_event event;
-
- event.events = EPOLLIN | EPOLLOUT | EPOLLET;
- event.data.ptr = connection;
- if (0 != epoll_ctl (daemon->events.data.epoll.e_fd,
- EPOLL_CTL_ADD,
- connection->sk.fd,
- &event))
- {
- mhd_LOG_MSG (daemon, MHD_SC_EPOLL_CTL_ADD_FAILED,
- "Failed to add connection socket to epoll.");
- res = MHD_SC_EPOLL_CTL_ADD_FAILED;
- }
- else
+ mhd_LOG_MSG (daemon, MHD_SC_EPOLL_CTL_ADD_FAILED,
+ "Failed to add connection socket to epoll.");
+ res = MHD_SC_EPOLL_CTL_ADD_FAILED;
+ }
+ else
+ {
+ mhd_dbg_print_fd_mon_req ("conn", \
+ connection->sk.fd, \
+ true, \
+ true, \
+ false);
+ if (0) // TODO: implement turbo
{
- mhd_dbg_print_fd_mon_req ("conn", \
- connection->sk.fd, \
- true, \
- true, \
- false);
- if (0) // TODO: implement turbo
- {
- connection->sk.ready =
- (enum mhd_SocketNetState) (mhd_SOCKET_NET_STATE_RECV_READY
- | mhd_SOCKET_NET_STATE_SEND_READY);
- mhd_conn_mark_ready (connection, daemon);
- }
- return MHD_SC_OK; /* *** Function success exit point *** */
+ connection->sk.ready =
+ (enum mhd_SocketNetState) (mhd_SOCKET_NET_STATE_RECV_READY
+ | mhd_SOCKET_NET_STATE_SEND_READY);
+ mhd_conn_mark_ready (connection, daemon);
}
+ return MHD_SC_OK; /* *** Function success exit point *** */
}
- else /* No 'epoll' */
-#endif /* MHD_SUPPORT_EPOLL */
- return MHD_SC_OK; /* *** Function success exit point *** */
}
+ else /* No 'epoll' */
+#endif /* MHD_SUPPORT_EPOLL */
+ return MHD_SC_OK; /* *** Function success exit point *** */
+ }
- /* ** Below is a cleanup path ** */
- mhd_assert (MHD_SC_OK != res);
- notify_app_conn (daemon, connection, true);
+ /* ** Below is a cleanup path ** */
+ mhd_assert (MHD_SC_OK != res);
+ notify_app_conn (daemon, connection, true);
- mhd_conn_deinit_activity_timeout (connection);
+ mhd_conn_deinit_activity_timeout (connection);
+
+ mhd_DLINKEDL_DEL (&(daemon->conns), connection, all_conn);
+ daemon->conns.count--;
+ daemon->conns.block_new = false;
- mhd_DLINKEDL_DEL (&(daemon->conns), connection, all_conn);
- daemon->conns.count--;
- daemon->conns.block_new = false;
- }
mhd_pool_destroy (connection->pool);
}
/* Free resources allocated before the call of this functions */
@@ -599,6 +596,8 @@ internal_add_connection (struct MHD_Daemon *daemon,
mhd_assert (! mhd_D_HAS_WORKERS (daemon));
mhd_assert (mhd_FD_FITS_DAEMON (daemon, client_socket));
+ res = MHD_SC_OK;
+
if ((! non_blck) &&
(mhd_POLL_TYPE_INT_IS_EPOLL (daemon->events.poll_type) ||
(mhd_WM_INT_EXTERNAL_EVENTS_EDGE == daemon->wmode_int)))
@@ -606,50 +605,47 @@ internal_add_connection (struct MHD_Daemon *daemon,
mhd_LOG_MSG (daemon, MHD_SC_NONBLOCKING_REQUIRED, \
"The daemon configuration requires non-blocking sockets, "
"the new socket has not been added.");
- (void) mhd_socket_close (client_socket);
- return MHD_SC_NONBLOCKING_REQUIRED;
+ res = MHD_SC_NONBLOCKING_REQUIRED;
}
- res = new_connection_prepare_ (daemon,
- client_socket,
- addr, addrlen,
- external_add,
- non_blck,
- sk_spipe_supprs,
- sk_is_nonip,
- &connection);
- if (MHD_SC_OK != res)
- return res;
-
- if (external_add) // TODO: support thread-unsafe
+
+ if (MHD_SC_OK == res)
{
- mhd_assert (0 && "Not implemented yet");
-#if 1 // TODO: support externally added
- return MHD_SC_FEATURE_DISABLED;
-#else
- /* Connection is added externally and MHD is thread safe mode. */
- MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
- DLL_insert (daemon->new_connections_head,
- daemon->new_connections_tail,
- connection);
- daemon->have_new = true;
- MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
-
- /* The rest of connection processing must be handled in
- * the daemon thread. */
- if ((mhd_ITC_IS_VALID (daemon->itc)) &&
- (! mhd_itc_activate (daemon->itc, "n")))
+ if (daemon->conns.block_new)
+ { /* Connections limit */
+ mhd_LOG_MSG (daemon, MHD_SC_LIMIT_CONNECTIONS_REACHED, \
+ "Server reached connection limit. " \
+ "Closing inbound connection.");
+ res = MHD_SC_LIMIT_CONNECTIONS_REACHED;
+ }
+
+ if (MHD_SC_OK == res)
{
-#ifdef HAVE_MESSAGES
- MHD_DLOG (daemon,
- _ ("Failed to signal new connection via inter-thread " \
- "communication channel.\n"));
-#endif
+ res = new_connection_prepare_ (daemon,
+ client_socket,
+ addr, addrlen,
+ external_add,
+ non_blck,
+ sk_spipe_supprs,
+ sk_is_nonip,
+ &connection);
+
+ if (MHD_SC_OK == res)
+ {
+ mhd_ASSUME (NULL != connection);
+
+ if (external_add)
+ res = MHD_SC_FEATURE_DISABLED;
+ else
+ return new_connection_process_ (daemon, connection);
+ }
}
- return MHD_YES;
-#endif
}
- return new_connection_process_ (daemon, connection);
+ mhd_socket_close (client_socket);
+
+ mhd_assert (MHD_SC_OK != res);
+
+ return res;
}