commit cdd4c1f9cc9686fc57ce9e5894c77fb70b3529c6
parent 427f40095ca485f1acad59c5d50ab26fe93da723
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Fri, 6 Jun 2025 15:59:25 +0200
get_all_net_updates_by_epoll(): reduced the size of the data passed to the kernel
Fixed possible wait for the second batch of epoll data
Diffstat:
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/src/mhd2/events_process.c b/src/mhd2/events_process.c
@@ -1578,6 +1578,7 @@ update_statuses_from_eevents (struct MHD_Daemon *restrict d,
static MHD_FN_PAR_NONNULL_ (1) bool
get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
{
+ int max_events;
int num_events;
unsigned int events_processed;
int max_wait;
@@ -1591,6 +1592,21 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
// TODO: add listen socket enable/disable
+ /* Minimise amount of data passed from userspace to kernel and back */
+ max_events = d->conns.cfg.count_limit;
+#ifdef MHD_SUPPORT_THREADS
+ ++max_events;
+#endif /* MHD_SUPPORT_THREADS */
+ if (MHD_INVALID_SOCKET != d->net.listen.fd)
+ ++max_events;
+ /* Make sure that one extra slot used to clearly detect that all events
+ * were gotten. */
+ ++max_events;
+ if (0 > max_events)
+ max_events = (int) (((unsigned int)~((unsigned int) 0)) >> 1);
+ if (max_events > (int) d->events.data.epoll.num_elements)
+ max_events = (int) d->events.data.epoll.num_elements;
+
events_processed = 0;
max_wait = get_max_wait (d); // TODO: use correct timeout value
do
@@ -1604,13 +1620,13 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
#endif /* mhd_DEBUG_POLLING_FDS */
num_events = epoll_wait (d->events.data.epoll.e_fd,
d->events.data.epoll.events,
- (int) d->events.data.epoll.num_elements,
+ max_events,
max_wait);
#ifdef mhd_DEBUG_POLLING_FDS
fprintf (stderr,
"### (Finished) epoll_wait(%d, events, %d, %d) -> %d\n",
d->events.data.epoll.e_fd,
- (int) d->events.data.epoll.num_elements,
+ max_events,
max_wait,
num_events);
#endif /* mhd_DEBUG_POLLING_FDS */
@@ -1628,11 +1644,16 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
}
if (! update_statuses_from_eevents (d, (unsigned int) num_events))
return false;
+ if (max_events > num_events)
+ return true; /* All events have been read */
+
+ /* Use all buffer for the next getting events round(s) */
+ max_events = d->events.data.epoll.num_elements;
+ max_wait = 0; /* Do not block on the next getting events rounds */
events_processed += (unsigned int) num_events; /* Avoid reading too many events */
- } while ((((unsigned int) num_events) == d->events.data.epoll.num_elements) &&
- ((events_processed < d->conns.cfg.count_limit)
- || (events_processed < d->conns.cfg.count_limit + 2)));
+ } while ((events_processed < d->conns.cfg.count_limit)
+ || (events_processed < d->conns.cfg.count_limit + 2));
return true;
}