Bladeren bron

Extended FD events debug print to internally polled FDs

Evgeny Grin (Karlson2k) 10 maanden geleden
bovenliggende
commit
66c34de2c9

+ 3 - 3
src/incl_priv/mhd_sys_options.h

@@ -516,9 +516,9 @@
 #  endif
 #endif
 
-#ifndef mhd_DEBUG_EXTR_EVENTS
-/* Use debug-print for external events processing */
-/* #  define mhd_DEBUG_EXTR_EVENTS 1 */
+#ifndef mhd_DEBUG_POLLING_FDS
+/* Use debug-print for FDs polling */
+/* #  define mhd_DEBUG_POLLING_FDS 1 */
 #endif
 
 #ifndef mhd_DEBUG_SUSPEND_RESUME

+ 1 - 0
src/mhd2/Makefile.am

@@ -46,6 +46,7 @@ libmicrohttpd2_la_SOURCES = \
   mhd_buffer.h \
   mhd_limits.h \
   mhd_iovec.h \
+  mhd_dbg_print.h \
   mhd_panic.c               mhd_panic.h \
   mhd_lib_init.c            mhd_lib_init_impl.h       mhd_lib_init.h \
   mhd_lib_init_auto.h \

+ 6 - 0
src/mhd2/daemon_add_conn.c

@@ -57,6 +57,7 @@
 #include "mhd_sockets_funcs.h"
 
 #include "mhd_panic.h"
+#include "mhd_dbg_print.h"
 
 #include "mhd_daemon.h"
 #include "mhd_connection.h"
@@ -396,6 +397,11 @@ new_connection_process_inner (struct MHD_Daemon *restrict daemon,
           }
           else
           {
+            mhd_dbg_print_fd_mon_req ("conn", \
+                                      connection->sk.fd, \
+                                      true, \
+                                      true, \
+                                      false);
             if (0) // TODO: implement turbo
             {
               connection->sk.ready = mhd_SOCKET_NET_STATE_RECV_READY

+ 4 - 4
src/mhd2/daemon_event_update.c

@@ -36,10 +36,10 @@
 
 #include "daemon_logger.h"
 
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
 #  include "mhd_itc.h"
 #  include <stdio.h>
-#endif /* mhd_DEBUG_EXTR_EVENTS */
+#endif /* mhd_DEBUG_POLLING_FDS */
 
 #include "mhd_public_api.h"
 
@@ -60,7 +60,7 @@ MHD_daemon_event_update (
   if (mhd_DAEMON_STATE_STARTED < daemon->state)
     return;
 
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
   if (1)
   {
     char state_str[] = "x:x:x";
@@ -96,7 +96,7 @@ MHD_daemon_event_update (
       break;
     }
   }
-#endif /* mhd_DEBUG_EXTR_EVENTS */
+#endif /* mhd_DEBUG_POLLING_FDS */
 
   broken_app_data = false;
   unneeded_event = false;

+ 16 - 4
src/mhd2/daemon_start.c

@@ -36,8 +36,6 @@
 #include "mhd_sockets_macros.h"
 #include "sys_ip_headers.h"
 
-#include "extr_events_funcs.h"
-
 #ifdef MHD_SOCKETS_KIND_POSIX
 #  include "sys_errno.h"
 #endif
@@ -64,6 +62,10 @@
 #  endif
 #endif
 
+#include "extr_events_funcs.h"
+
+#include "mhd_dbg_print.h"
+
 #include "mhd_limits.h"
 
 #include "mhd_daemon.h"
@@ -2189,9 +2191,14 @@ init_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
                           mhd_itc_r_fd (d->threading.itc), &reg_event))
       {
         mhd_LOG_MSG (d, MHD_SC_EPOLL_ADD_DAEMON_FDS_FAILURE, \
-                     "Failed to add ITC fd to the epoll monitoring.");
+                     "Failed to add ITC FD to the epoll monitoring.");
         return MHD_SC_EPOLL_ADD_DAEMON_FDS_FAILURE;
       }
+      mhd_dbg_print_fd_mon_req ("ITC", \
+                                mhd_itc_r_fd (d->threading.itc), \
+                                true, \
+                                false, \
+                                false);
 #endif
       if (MHD_INVALID_SOCKET != d->net.listen.fd)
       {
@@ -2201,9 +2208,14 @@ init_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
                             d->net.listen.fd, &reg_event))
         {
           mhd_LOG_MSG (d, MHD_SC_EPOLL_ADD_DAEMON_FDS_FAILURE, \
-                       "Failed to add listening fd to the epoll monitoring.");
+                       "Failed to add listening FD to the epoll monitoring.");
           return MHD_SC_EPOLL_ADD_DAEMON_FDS_FAILURE;
         }
+        mhd_dbg_print_fd_mon_req ("lstn", \
+                                  d->net.listen.fd, \
+                                  true, \
+                                  false, \
+                                  false);
       }
     }
     return MHD_SC_OK;

+ 220 - 4
src/mhd2/events_process.c

@@ -30,7 +30,7 @@
 #include "mhd_assert.h"
 #include "mhd_unreachable.h"
 
-#ifdef mhd_DEBUG_SUSPEND_RESUME
+#if defined(mhd_DEBUG_SUSPEND_RESUME) || defined(mhd_DEBUG_POLLING_FDS)
 #  include <stdio.h>
 #endif /* mhd_DEBUG_SUSPEND_RESUME */
 
@@ -49,6 +49,7 @@
 #include "mhd_itc.h"
 
 #include "mhd_panic.h"
+#include "mhd_dbg_print.h"
 
 #include "mhd_sockets_macros.h"
 
@@ -69,6 +70,68 @@
 
 #include "mhd_public_api.h"
 
+#if mhd_DEBUG_POLLING_FDS
+/**
+ * Debug-printf request of FD polling/monitoring
+ * @param fd_name the name of FD ("ITC", "lstn" or "conn")
+ * @param fd the FD value
+ * @param r_ready the request for read (or receive) readiness
+ * @param w_ready the request for write (or send) readiness
+ * @param e_ready the request for exception (or error) readiness
+ */
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void
+mhd_dbg_print_fd_mon_req (const char *fd_name,
+                          MHD_Socket fd,
+                          bool r_ready,
+                          bool w_ready,
+                          bool e_ready)
+{
+  char state_str[] = "x:x:x";
+  state_str[0] = r_ready ? 'R' : '-';
+  state_str[2] = w_ready ? 'W' : '-';
+  state_str[4] = e_ready ? 'E' : '-';
+
+  fprintf (stderr,
+           "### Set FD watching: %4s [%llu] for %s\n",
+           fd_name,
+           (unsigned long long) fd,
+           state_str);
+}
+
+
+/**
+ * Debug-printf reported (by polling) status of FD
+ * @param fd_name the name of FD ("ITC", "lstn" or "conn")
+ * @param fd the FD value
+ * @param r_ready the read (or receive) readiness
+ * @param w_ready the write (or send) readiness
+ * @param e_ready the exception (or error) readiness
+ */
+static MHD_FN_PAR_NONNULL_ALL_ void
+dbg_print_fd_state_update (const char *fd_name,
+                           MHD_Socket fd,
+                           bool r_ready,
+                           bool w_ready,
+                           bool e_ready)
+{
+  char state_str[] = "x:x:x";
+  state_str[0] = r_ready ? 'R' : '-';
+  state_str[2] = w_ready ? 'W' : '-';
+  state_str[4] = e_ready ? 'E' : '-';
+
+  fprintf (stderr,
+           "### FD state update: %4s [%llu]  -> %s\n",
+           fd_name,
+           (unsigned long long) fd,
+           state_str);
+}
+
+
+#else  /* ! mhd_DEBUG_POLLING_FDS */
+#  defined dbg_print_fd_state_update (fd_n,fd,r_ready,w_ready,e_ready) ((void) 0 \
+                                                                        )
+#endif /* ! mhd_DEBUG_POLLING_FDS */
+
 /**
  * Log error message about broken ITC
  * @param d the daemon to use
@@ -102,12 +165,37 @@ mhd_daemon_get_wait_max (struct MHD_Daemon *restrict d)
   mhd_assert (! mhd_D_HAS_WORKERS (d));
 
   if (d->events.accept_pending && ! d->conns.block_new)
+  {
+#ifdef mhd_DEBUG_POLLING_FDS
+    fprintf (stderr,
+             "### mhd_daemon_get_wait_max(daemon) -> zero "
+             "(accept new conn pending)\n");
+#endif
     return 0;
+  }
   if (d->threading.resume_requested) /* Remove? It is triggered by ITC anyway */
+  {
+#ifdef mhd_DEBUG_POLLING_FDS
+    fprintf (stderr,
+             "### mhd_daemon_get_wait_max(daemon) -> zero "
+             "(resume connection pending)\n");
+#endif
     return 0;
+  }
   if (NULL != mhd_DLINKEDL_GET_FIRST (&(d->events), proc_ready))
+  {
+#ifdef mhd_DEBUG_POLLING_FDS
+    fprintf (stderr,
+             "### mhd_daemon_get_wait_max(daemon) -> zero "
+             "(connection(s) is already ready)\n");
+#endif
     return 0;
+  }
 
+#ifdef mhd_DEBUG_POLLING_FDS
+  fprintf (stderr,
+           "### mhd_daemon_get_wait_max(daemon) -> MHD_WAIT_INDEFINITELY\n");
+#endif
   return MHD_WAIT_INDEFINITELY; // TODO: calculate correct timeout value
 }
 
@@ -185,6 +273,12 @@ update_conn_net_status (struct MHD_Daemon *restrict d,
   /* "resuming" must be not processed yet */
   mhd_assert (! c->resuming || c->suspended);
 
+  dbg_print_fd_state_update ("conn", \
+                             c->sk.fd, \
+                             recv_ready, \
+                             send_ready, \
+                             err_state);
+
   sk_state = mhd_SOCKET_NET_STATE_NOTHING;
   if (recv_ready)
     sk_state = (enum mhd_SocketNetState)
@@ -751,6 +845,11 @@ select_update_fdsets (struct MHD_Daemon *restrict d,
                efds,
                &ret,
                d);
+  mhd_dbg_print_fd_mon_req ("ITC", \
+                            mhd_itc_r_fd (d->threading.itc), \
+                            true, \
+                            false, \
+                            true);
 #endif
   if ((MHD_INVALID_SOCKET != d->net.listen.fd)
       && ! d->conns.block_new)
@@ -765,6 +864,11 @@ select_update_fdsets (struct MHD_Daemon *restrict d,
                  efds,
                  &ret,
                  d);
+    mhd_dbg_print_fd_mon_req ("lstn", \
+                              d->net.listen.fd, \
+                              true, \
+                              false, \
+                              true);
   }
   if (listen_only)
     return ret;
@@ -790,6 +894,11 @@ select_update_fdsets (struct MHD_Daemon *restrict d,
                  efds,
                  &ret,
                  d);
+    mhd_dbg_print_fd_mon_req ("conn", \
+                              c->sk.fd, \
+                              FD_ISSET (c->sk.fd, rfds), \
+                              FD_ISSET (c->sk.fd, wfds), \
+                              true);
   }
 
   return ret;
@@ -824,6 +933,11 @@ select_update_statuses_from_fdsets_and_resume_conn (struct MHD_Daemon *d,
 
 #ifdef MHD_SUPPORT_THREADS
   mhd_assert (mhd_ITC_IS_VALID (d->threading.itc));
+  dbg_print_fd_state_update ("ITC", \
+                             mhd_itc_r_fd (d->threading.itc), \
+                             FD_ISSET (mhd_itc_r_fd (d->threading.itc), rfds), \
+                             FD_ISSET (mhd_itc_r_fd (d->threading.itc), wfds), \
+                             FD_ISSET (mhd_itc_r_fd (d->threading.itc), efds));
   if (FD_ISSET (mhd_itc_r_fd (d->threading.itc), efds))
   {
     log_itc_broken (d);
@@ -850,6 +964,11 @@ select_update_statuses_from_fdsets_and_resume_conn (struct MHD_Daemon *d,
   if (MHD_INVALID_SOCKET != d->net.listen.fd)
   {
     mhd_assert (! d->net.listen.is_broken);
+    dbg_print_fd_state_update ("lstn", \
+                               d->net.listen.fd, \
+                               FD_ISSET (d->net.listen.fd, rfds), \
+                               FD_ISSET (d->net.listen.fd, wfds), \
+                               FD_ISSET (d->net.listen.fd, efds));
     if (FD_ISSET (d->net.listen.fd, efds))
     {
       --num_events;
@@ -960,11 +1079,27 @@ get_all_net_updates_by_select_and_resume_conn (struct MHD_Daemon *restrict d,
   tmvl.tv_usec = (int) ((max_wait % 1000) * 1000);
 #endif
 
+#if mhd_DEBUG_POLLING_FDS
+  fprintf (stderr,
+           "### (Starting) select(%d, rfds, wfds, efds, [%llu, %llu])...\n",
+           max_socket + 1,
+           (unsigned long long) tmvl.tv_sec,
+           (unsigned long long) tmvl.tv_usec);
+#endif /* mhd_DEBUG_POLLING_FDS */
   num_events = select (max_socket + 1,
                        d->events.data.select.rfds,
                        d->events.data.select.wfds,
                        d->events.data.select.efds,
                        &tmvl);
+#if mhd_DEBUG_POLLING_FDS
+  fprintf (stderr,
+           "### (Finished) select(%d, rfds, wfds, efds, ->[%llu, %llu]) -> "
+           "%d\n",
+           max_socket + 1,
+           (unsigned long long) tmvl.tv_sec,
+           (unsigned long long) tmvl.tv_usec,
+           num_events);
+#endif /* mhd_DEBUG_POLLING_FDS */
 
   if (0 > num_events)
   {
@@ -1028,8 +1163,14 @@ poll_update_fds (struct MHD_Daemon *restrict d,
   mhd_assert (mhd_ITC_IS_VALID (d->threading.itc));
   mhd_assert (d->events.data.poll.fds[i_s].fd == \
               mhd_itc_r_fd (d->threading.itc));
+  mhd_assert (POLLIN == d->events.data.poll.fds[i_s].events);
   mhd_assert (mhd_SOCKET_REL_MARKER_ITC == \
               d->events.data.poll.rel[i_s].fd_id);
+  mhd_dbg_print_fd_mon_req ("ITC", \
+                            mhd_itc_r_fd (d->threading.itc), \
+                            true, \
+                            false, \
+                            false);
   ++i_s;
 #endif
   if (MHD_INVALID_SOCKET != d->net.listen.fd)
@@ -1039,6 +1180,11 @@ poll_update_fds (struct MHD_Daemon *restrict d,
     mhd_assert (mhd_SOCKET_REL_MARKER_LISTEN == \
                 d->events.data.poll.rel[i_s].fd_id);
     d->events.data.poll.fds[i_s].events = d->conns.block_new ? 0 : POLLIN;
+    mhd_dbg_print_fd_mon_req ("lstn", \
+                              d->net.listen.fd, \
+                              POLLIN == d->events.data.poll.fds[i_s].events, \
+                              false, \
+                              false);
     ++i_s;
   }
   if (listen_only)
@@ -1071,6 +1217,11 @@ poll_update_fds (struct MHD_Daemon *restrict d,
       events |= MHD_POLL_OUT;
 
     d->events.data.poll.fds[i_c].events = (short) events;
+    mhd_dbg_print_fd_mon_req ("conn", \
+                              c->sk.fd, \
+                              MHD_POLL_IN == (MHD_POLL_IN & events), \
+                              MHD_POLL_OUT == (MHD_POLL_OUT & events), \
+                              false);
     ++i_c;
   }
   mhd_assert ((d->conns.count - num_skipped) == (i_c - i_s));
@@ -1099,6 +1250,13 @@ poll_update_statuses_from_fds (struct MHD_Daemon *restrict d,
               mhd_itc_r_fd (d->threading.itc));
   mhd_assert (mhd_SOCKET_REL_MARKER_ITC == \
               d->events.data.poll.rel[i_s].fd_id);
+  dbg_print_fd_state_update ( \
+    "ITC", \
+    d->events.data.poll.fds[i_s].fd, \
+    0 != (d->events.data.poll.fds[i_s].revents & (MHD_POLL_IN | POLLIN)), \
+    0 != (d->events.data.poll.fds[i_s].revents & (MHD_POLL_OUT | POLLOUT)), \
+    0 != (d->events.data.poll.fds[i_s].revents & (POLLERR | POLLNVAL)));
+
   if (0 != (d->events.data.poll.fds[i_s].revents & (POLLERR | POLLNVAL)))
   {
     log_itc_broken (d);
@@ -1129,6 +1287,11 @@ poll_update_statuses_from_fds (struct MHD_Daemon *restrict d,
     mhd_assert (d->events.data.poll.fds[i_s].fd == d->net.listen.fd);
     mhd_assert (mhd_SOCKET_REL_MARKER_LISTEN == \
                 d->events.data.poll.rel[i_s].fd_id);
+    dbg_print_fd_state_update ("lstn", \
+                               d->events.data.poll.fds[i_s].fd, \
+                               0 != (revents & (MHD_POLL_IN | POLLIN)), \
+                               0 != (revents & (MHD_POLL_OUT | POLLOUT)), \
+                               0 != (revents & (POLLERR | POLLNVAL | POLLHUP)));
     if (0 != (revents & (POLLERR | POLLNVAL | POLLHUP)))
     {
       --num_events;
@@ -1221,17 +1384,42 @@ static MHD_FN_PAR_NONNULL_ (1) bool
 get_all_net_updates_by_poll (struct MHD_Daemon *restrict d,
                              bool listen_only)
 {
+#if mhd_DEBUG_POLLING_FDS
+#  ifdef MHD_SOCKETS_KIND_POSIX
+  static const char poll_fn_name[] = "poll";
+#  else  /* MHD_SOCKETS_KIND_WINSOCK */
+  static const char poll_fn_name[] = "WSAPoll";
+#  endif /* MHD_SOCKETS_KIND_WINSOCK */
+#endif /* mhd_DEBUG_POLLING_FDS */
   unsigned int num_fds;
+  int max_wait;
   int num_events;
+
   mhd_assert (mhd_POLL_TYPE_POLL == d->events.poll_type);
 
   num_fds = poll_update_fds (d, listen_only);
 
   // TODO: handle empty list situation
+  max_wait = get_max_wait (d); // TODO: use correct timeout value
 
+#if mhd_DEBUG_POLLING_FDS
+  fprintf (stderr,
+           "### (Starting) %s(fds, %u, %d)...\n",
+           poll_fn_name,
+           num_fds,
+           max_wait);
+#endif /* mhd_DEBUG_POLLING_FDS */
   num_events = mhd_poll (d->events.data.poll.fds,
                          num_fds,
-                         get_max_wait (d)); // TODO: use correct timeout value
+                         max_wait); // TODO: use correct timeout value
+#if mhd_DEBUG_POLLING_FDS
+  fprintf (stderr,
+           "### (Finished) %s(fds, %u, %d) -> %d\n",
+           poll_fn_name,
+           num_fds,
+           max_wait,
+           num_events);
+#endif /* mhd_DEBUG_POLLING_FDS */
   if (0 > num_events)
   {
     int err;
@@ -1292,6 +1480,13 @@ update_statuses_from_eevents (struct MHD_Daemon *restrict d,
     if (((uint64_t) mhd_SOCKET_REL_MARKER_ITC) == e->data.u64) /* uint64_t is in the system header */
     {
       mhd_assert (mhd_ITC_IS_VALID (d->threading.itc));
+      dbg_print_fd_state_update ( \
+        "ITC", \
+        mhd_itc_r_fd (d->threading.itc), \
+        0 != (e->events & EPOLLIN), \
+        0 != (e->events & EPOLLOUT), \
+        0 != (e->events & (EPOLLPRI | EPOLLERR | EPOLLHUP)));
+
       if (0 != (e->events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
       {
         log_itc_broken (d);
@@ -1313,6 +1508,12 @@ update_statuses_from_eevents (struct MHD_Daemon *restrict d,
     if (((uint64_t) mhd_SOCKET_REL_MARKER_LISTEN) == e->data.u64) /* uint64_t is in the system header */
     {
       mhd_assert (MHD_INVALID_SOCKET != d->net.listen.fd);
+      dbg_print_fd_state_update ( \
+        "lstn", \
+        d->net.listen.fd, \
+        0 != (e->events & EPOLLIN), \
+        0 != (e->events & EPOLLOUT), \
+        0 != (e->events & (EPOLLPRI | EPOLLERR | EPOLLHUP)));
       if (0 != (e->events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
       {
         log_listen_broken (d);
@@ -1380,10 +1581,25 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict d)
   max_wait = get_max_wait (d); // TODO: use correct timeout value
   do
   {
+#if mhd_DEBUG_POLLING_FDS
+    fprintf (stderr,
+             "### (Starting) epoll_wait(%d, events, %d, %d)...\n",
+             d->events.data.epoll.e_fd,
+             (int) d->events.data.epoll.num_elements,
+             max_wait);
+#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_wait);
+#if 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_wait,
+             num_events);
+#endif /* mhd_DEBUG_POLLING_FDS */
     max_wait = 0;
     if (0 > num_events)
     {
@@ -1541,14 +1757,14 @@ MHD_daemon_process_reg_events (struct MHD_Daemon *MHD_RESTRICT daemon,
                                uint_fast64_t *MHD_RESTRICT next_max_wait)
 {
   enum MHD_StatusCode res;
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
   fprintf (stderr,
            "### (Started)  MHD_daemon_process_reg_events(daemon, [%s])...\n",
            (NULL != next_max_wait) ? "non-NULL" : "NULL");
 #endif
   res = process_reg_events_int (daemon,
                                 next_max_wait);
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
   if (NULL == next_max_wait)
     fprintf (stderr,
              "### (Finished) MHD_daemon_process_reg_events(daemon, [NULL]) ->"

+ 5 - 5
src/mhd2/extr_events_funcs.h

@@ -29,12 +29,12 @@
 
 #include "mhd_sys_options.h"
 
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
 #  include <stdio.h>
 #  include "mhd_daemon.h"
 #  include "mhd_assert.h"
 #  include "sys_null_macro.h"
-#endif /* mhd_DEBUG_EXTR_EVENTS */
+#endif /* mhd_DEBUG_POLLING_FDS */
 
 #ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
 
@@ -55,7 +55,7 @@ mhd_log_extr_event_dereg_failed (struct MHD_Daemon *restrict d);
 
 #endif /* ! MHD_SUPPORT_LOG_FUNCTIONALITY */
 
-#ifdef mhd_DEBUG_EXTR_EVENTS
+#ifdef mhd_DEBUG_POLLING_FDS
 /**
  * Call application event registration callback
  * @param d the daemon to use
@@ -123,12 +123,12 @@ mhd_daemon_extr_event_reg (struct MHD_Daemon *d,
 
   return res;
 }
-#else  /* ! mhd_DEBUG_EXTR_EVENTS */
+#else  /* ! mhd_DEBUG_POLLING_FDS */
 #  define mhd_daemon_extr_event_reg(d,fd,w_for,app_cntx_old,ecb_cntx) \
         d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls, \
                                         fd, w_for, app_cntx_old, ecb_cntx)
 
-#endif /* ! mhd_DEBUG_EXTR_EVENTS */
+#endif /* ! mhd_DEBUG_POLLING_FDS */
 
 
 #endif /* ! MHD_EXTR_EVENTS_FUNCS_H */

+ 61 - 0
src/mhd2/mhd_dbg_print.h

@@ -0,0 +1,61 @@
+/*
+  This file is part of GNU libmicrohttpd
+  Copyright (C) 2025 Evgeny Grin (Karlson2k)
+
+  GNU libmicrohttpd is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  GNU libmicrohttpd is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+*/
+
+/**
+ * @file src/mhd2/mhd_dbg_print.h
+ * @brief  The declarations of interl debug-print helpers
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_DBG_PRINT_H
+#define MHD_DBG_PRINT_H 1
+
+#include "mhd_sys_options.h"
+
+#ifdef mhd_DEBUG_POLLING_FDS
+#  include "sys_bool_type.h"
+#  include "mhd_socket_type.h"
+#endif /* mhd_DEBUG_POLLING_FDS */
+
+
+#if mhd_DEBUG_POLLING_FDS
+/**
+ * Debug-printf request of FD polling/monitoring
+ * @param fd_name the name of FD ("ITC", "lstn" or "conn")
+ * @param fd the FD value
+ * @param r_ready the request for read (or receive) readiness
+ * @param w_ready the request for write (or send) readiness
+ * @param e_ready the request for exception (or error) readiness
+ * @note Implemented in src/mhd2/events_process.c
+ */
+MHD_INTERNAL void
+mhd_dbg_print_fd_mon_req (const char *fd_name,
+                          MHD_Socket fd,
+                          bool r_ready,
+                          bool w_ready,
+                          bool e_ready)
+MHD_FN_PAR_NONNULL_ALL_;
+
+#else  /* ! mhd_DEBUG_POLLING_FDS */
+#  define dbg_print_fd_state_update(fd_n,fd,r_ready,w_ready,e_ready) ((void) 0)
+#endif /* ! mhd_DEBUG_POLLING_FDS */
+
+
+#endif /* ! MHD_DBG_PRINT_H */