Răsfoiți Sursa

MHD_daemon_get_info_dynamic_sz(): implemented

Evgeny Grin (Karlson2k) 1 an în urmă
părinte
comite
de741e6926

+ 43 - 25
src/include/microhttpd2.h

@@ -9315,7 +9315,7 @@ MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
 enum MHD_DaemonInfoDynamicType
 {
   /**
-   * The the maximum number of microseconds from the current moment until
+   * The the maximum number of millisecond from the current moment until
    * the mandatory call of the daemon data processing function (like
    * #MHD_deamon_process_reg_events(), #MHD_daemon_process_blocking()).
    * If resulting value is zero then daemon data processing function should be
@@ -9324,19 +9324,17 @@ enum MHD_DaemonInfoDynamicType
    * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC,
    * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE
    * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
+   * The function return #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if daemon has
+   * internal handling of events (internal threads).
    * The result is placed in @a v_uint64 member.
    */
   MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1
   ,
   /**
-   * Request the number of current connections handled by the daemon.
-   * No extra arguments should be passed.
-   * Note: when using MHD without internal threads, this type of request
-   * could be used only when MHD is is not processing the connection data
-   * in other thread at the same time.
-   * The result is placed in @a v_uint member.
+   * Check whether the daemon has any connected network clients.
+   * The result is placed in @a v_bool member.
    */
-  MHD_DAEMON_INFO_DYNAMIC_CURRENT_CONNECTIONS = 20
+  MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20
   ,
   /* * Sentinel * */
   /**
@@ -9354,14 +9352,14 @@ enum MHD_DaemonInfoDynamicType
 union MHD_DaemonInfoDynamicData
 {
   /**
-   * Unsigned 64 bits integer value.
+   * The boolean value
    */
-  uint_fast64_t v_uint64;
+  enum MHD_Bool v_bool;
 
   /**
-   * Unsigned integer value.
+   * Unsigned 64 bits integer value.
    */
-  unsigned int v_uint;
+  uint_fast64_t v_uint64;
 
   /**
    * Unused member.
@@ -9379,19 +9377,30 @@ union MHD_DaemonInfoDynamicData
  *
  * @param daemon the daemon to get information about
  * @param info_type the type of information requested
- * @param[out] return_value pointer to union where requested information will
- *                          be stored
- * @param return_value_size the size of the memory area pointed
- *                          by @a return_data, in bytes
+ * @param[out] output_buf the pointer to union to be set to the requested
+ *                        information
+ * @param output_buf_size the size of the memory area pointed by @a output_buf
+ *                        (provided by the caller for storing the requested
+ *                        information), in bytes
  * @return #MHD_SC_OK if succeed,
- *         error code otherwise
+ *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
+ *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
+ *                                              is not available for this
+ *                                              daemon due to the daemon
+ *                                              configuration/mode,
+ *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
+ *                                            should be available for
+ *                                            the daemon, but cannot be provided
+ *                                            due to some error or other
+ *                                            reasons,
+ *         other error code in case of other errors
  * @ingroup specialized
  */
 MHD_EXTERN_ enum MHD_StatusCode
 MHD_daemon_get_info_dynamic_sz (struct MHD_Daemon *daemon,
                                 enum MHD_DaemonInfoDynamicType info_type,
-                                union MHD_DaemonInfoDynamicData *return_value,
-                                size_t return_value_size)
+                                union MHD_DaemonInfoDynamicData *output_buf,
+                                size_t output_buf_size)
 MHD_FN_PAR_NONNULL_ (1)
 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
 
@@ -9401,15 +9410,24 @@ MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  *
  * @param daemon the daemon to get information about
  * @param info_type the type of information requested
- * @param[out] return_value pointer to union where requested information will
- *                          be stored
+ * @param[out] output_buf the pointer to union to be set to the requested
+ *                        information
  * @return #MHD_SC_OK if succeed,
- *         error code otherwise
+ *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
+ *                                              is not available for this
+ *                                              daemon due to the daemon
+ *                                              configuration/mode,
+ *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
+ *                                            should be available for
+ *                                            the daemon, but cannot be provided
+ *                                            due to some error or other
+ *                                            reasons,
+ *         other error code in case of other errors
  * @ingroup specialized
  */
-#define MHD_daemon_get_info_dynamic(daemon,info_type,return_value) \
-        MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (return_value), \
-                                        sizeof(*(return_value)))
+#define MHD_daemon_get_info_dynamic(daemon,info_type,output_buf) \
+        MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \
+                                        sizeof(*(output_buf)))
 
 
 /**

+ 43 - 25
src/include/microhttpd2_main.h.in

@@ -4693,7 +4693,7 @@ MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
 enum MHD_DaemonInfoDynamicType
 {
   /**
-   * The the maximum number of microseconds from the current moment until
+   * The the maximum number of millisecond from the current moment until
    * the mandatory call of the daemon data processing function (like
    * #MHD_deamon_process_reg_events(), #MHD_daemon_process_blocking()).
    * If resulting value is zero then daemon data processing function should be
@@ -4702,19 +4702,17 @@ enum MHD_DaemonInfoDynamicType
    * Available only for daemons stated in #MHD_WM_EXTERNAL_PERIODIC,
    * #MHD_WM_EXTERNAL_EVENT_LOOP_CB_LEVEL, #MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE
    * or #MHD_WM_EXTERNAL_SINGLE_FD_WATCH modes.
+   * The function return #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if daemon has
+   * internal handling of events (internal threads).
    * The result is placed in @a v_uint64 member.
    */
   MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT = 1
   ,
   /**
-   * Request the number of current connections handled by the daemon.
-   * No extra arguments should be passed.
-   * Note: when using MHD without internal threads, this type of request
-   * could be used only when MHD is is not processing the connection data
-   * in other thread at the same time.
-   * The result is placed in @a v_uint member.
+   * Check whether the daemon has any connected network clients.
+   * The result is placed in @a v_bool member.
    */
-  MHD_DAEMON_INFO_DYNAMIC_CURRENT_CONNECTIONS = 20
+  MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS = 20
   ,
   /* * Sentinel * */
   /**
@@ -4732,14 +4730,14 @@ enum MHD_DaemonInfoDynamicType
 union MHD_DaemonInfoDynamicData
 {
   /**
-   * Unsigned 64 bits integer value.
+   * The boolean value
    */
-  uint_fast64_t v_uint64;
+  enum MHD_Bool v_bool;
 
   /**
-   * Unsigned integer value.
+   * Unsigned 64 bits integer value.
    */
-  unsigned int v_uint;
+  uint_fast64_t v_uint64;
 
   /**
    * Unused member.
@@ -4757,19 +4755,30 @@ union MHD_DaemonInfoDynamicData
  *
  * @param daemon the daemon to get information about
  * @param info_type the type of information requested
- * @param[out] return_value pointer to union where requested information will
- *                          be stored
- * @param return_value_size the size of the memory area pointed
- *                          by @a return_data, in bytes
+ * @param[out] output_buf the pointer to union to be set to the requested
+ *                        information
+ * @param output_buf_size the size of the memory area pointed by @a output_buf
+ *                        (provided by the caller for storing the requested
+ *                        information), in bytes
  * @return #MHD_SC_OK if succeed,
- *         error code otherwise
+ *         #MHD_SC_INFO_GET_BUFF_TOO_SMALL if @a output_buf_size is too small,
+ *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
+ *                                              is not available for this
+ *                                              daemon due to the daemon
+ *                                              configuration/mode,
+ *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
+ *                                            should be available for
+ *                                            the daemon, but cannot be provided
+ *                                            due to some error or other
+ *                                            reasons,
+ *         other error code in case of other errors
  * @ingroup specialized
  */
 MHD_EXTERN_ enum MHD_StatusCode
 MHD_daemon_get_info_dynamic_sz (struct MHD_Daemon *daemon,
                                 enum MHD_DaemonInfoDynamicType info_type,
-                                union MHD_DaemonInfoDynamicData *return_value,
-                                size_t return_value_size)
+                                union MHD_DaemonInfoDynamicData *output_buf,
+                                size_t output_buf_size)
 MHD_FN_PAR_NONNULL_ (1)
 MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
 
@@ -4779,15 +4788,24 @@ MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3);
  *
  * @param daemon the daemon to get information about
  * @param info_type the type of information requested
- * @param[out] return_value pointer to union where requested information will
- *                          be stored
+ * @param[out] output_buf the pointer to union to be set to the requested
+ *                        information
  * @return #MHD_SC_OK if succeed,
- *         error code otherwise
+ *         #MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE if the requested information
+ *                                              is not available for this
+ *                                              daemon due to the daemon
+ *                                              configuration/mode,
+ *         #MHD_SC_INFO_GET_TYPE_UNOBTAINABLE if the requested information
+ *                                            should be available for
+ *                                            the daemon, but cannot be provided
+ *                                            due to some error or other
+ *                                            reasons,
+ *         other error code in case of other errors
  * @ingroup specialized
  */
-#define MHD_daemon_get_info_dynamic(daemon,info_type,return_value) \
-        MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (return_value), \
-                                        sizeof(*(return_value)))
+#define MHD_daemon_get_info_dynamic(daemon,info_type,output_buf) \
+        MHD_daemon_get_info_dynamic_sz ((daemon), (info_type), (output_buf), \
+                                        sizeof(*(output_buf)))
 
 
 /**

+ 56 - 0
src/mhd2/daemon_get_info.c

@@ -31,6 +31,7 @@
 
 #include "mhd_socket_type.h"
 #include "mhd_daemon.h"
+#include "events_process.h"
 
 #include "mhd_public_api.h"
 
@@ -84,3 +85,58 @@ MHD_daemon_get_info_fixed_sz (struct MHD_Daemon *daemon,
   }
   return MHD_SC_INFO_GET_TYPE_UNKNOWN;
 }
+
+
+MHD_EXTERN_
+MHD_FN_PAR_NONNULL_ (1)
+MHD_FN_PAR_NONNULL_ (3) MHD_FN_PAR_OUT_ (3) enum MHD_StatusCode
+MHD_daemon_get_info_dynamic_sz (struct MHD_Daemon *daemon,
+                                enum MHD_DaemonInfoDynamicType info_type,
+                                union MHD_DaemonInfoDynamicData *output_buf,
+                                size_t output_buf_size)
+{
+  switch (info_type)
+  {
+  case MHD_DAEMON_INFO_DYNAMIC_MAX_TIME_TO_WAIT:
+    if (mhd_WM_INT_HAS_THREADS (daemon->wmode_int))
+      return MHD_SC_INFO_GET_TYPE_NOT_APPLICABLE;
+    if (sizeof(output_buf->v_uint64) > output_buf_size)
+      return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
+    output_buf->v_uint64 = mhd_daemon_get_wait_max (daemon);
+    return MHD_SC_OK;
+  case MHD_DAEMON_INFO_DYNAMIC_HAS_CONNECTIONS:
+    if (sizeof(output_buf->v_bool) <= output_buf_size)
+    {
+      enum MHD_Bool res;
+      /*
+         Reading number of connection from the daemon member could be non-atomic
+         and may give wrong result (if it is modified in other thread), however
+         test against zero/non-zero value is valid even if reading is
+         non-atomic.
+       */
+      if (! mhd_D_HAS_WORKERS (daemon))
+        res = (0 != daemon->conns.count) ? MHD_YES : MHD_NO;
+      else
+      {
+        unsigned int i;
+        res = MHD_NO;
+        mhd_assert (NULL != daemon->threading.hier.pool.workers);
+        for (i = 0; i < daemon->threading.hier.pool.num; ++i)
+        {
+          if (0 != daemon->threading.hier.pool.workers[i].conns.count)
+          {
+            res = MHD_YES;
+            break;
+          }
+        }
+      }
+      output_buf->v_bool = res;
+      return MHD_SC_OK;
+    }
+    return MHD_SC_INFO_GET_BUFF_TOO_SMALL;
+  case MHD_DAEMON_INFO_DYNAMIC_SENTINEL:
+  default:
+    break;
+  }
+  return MHD_SC_INFO_GET_TYPE_UNKNOWN;
+}

+ 29 - 4
src/mhd2/events_process.c

@@ -64,14 +64,16 @@
 
 #include "mhd_public_api.h"
 
-static int
-get_max_wait (struct MHD_Daemon *restrict d)
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ uint_fast64_t
+mhd_daemon_get_wait_max (struct MHD_Daemon *restrict d)
 {
   bool zero_wait = d->events.zero_wait;
+
+  mhd_assert (! mhd_D_HAS_WORKERS (d));
+
   if (d->events.act_req.accept && d->conns.block_new)
     d->events.act_req.accept = false;
 
-  d->events.zero_wait = false; /* Reset as this pending data will be processed */
   if (d->events.act_req.accept)
     return 0;
   if (zero_wait)
@@ -79,10 +81,33 @@ get_max_wait (struct MHD_Daemon *restrict d)
   if (NULL != mhd_DLINKEDL_GET_FIRST (&(d->events), proc_ready))
     return 0;
 
-  return INT_MAX; // TODO: calculate correct timeout value
+  return MHD_WAIT_INDEFINITELY; // TODO: calculate correct timeout value
 }
 
 
+mhd_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE
+
+static MHD_FN_PAR_NONNULL_ALL_ int
+get_max_wait (struct MHD_Daemon *restrict d)
+{
+  uint_fast64_t ui64_wait = mhd_daemon_get_wait_max (d);
+  int i_wait = (int) ui64_wait;
+
+  // TODO: move reset to the processing loop
+  d->events.zero_wait = false; /* Reset as this pending data will be processed */
+
+  if ((0 > i_wait) ||
+      (ui64_wait != (uint_fast64_t) i_wait))
+    return INT_MAX;
+
+  return i_wait;
+}
+
+
+mhd_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE
+/* End of warning-less data truncation */
+
+
 MHD_FN_PAR_NONNULL_ (1) static void
 update_conn_net_status (struct MHD_Daemon *restrict d,
                         struct MHD_Connection *restrict c,

+ 14 - 0
src/mhd2/events_process.h

@@ -29,8 +29,12 @@
 
 #include "mhd_sys_options.h"
 
+#include "sys_base_types.h"
+
 #include "sys_thread_entry_type.h"
 
+struct MHD_Daemon; /* forward declaration */
+
 /**
  * The entry point for the daemon worker thread
  * @param cls the closure
@@ -52,4 +56,14 @@ mhd_worker_listening_only (void *cls);
 mhd_THRD_RTRN_TYPE mhd_THRD_CALL_SPEC
 mhd_worker_connection (void *cls);
 
+/**
+ * Get maximum wait time for the daemon
+ * @param d the daemon to check
+ * @return the maximum wait time,
+ *         #MHD_WAIT_INDEFINITELY if wait time is not limited
+ */
+MHD_INTERNAL uint_fast64_t
+mhd_daemon_get_wait_max (struct MHD_Daemon *restrict d)
+MHD_FN_PAR_NONNULL_ALL_;
+
 #endif /* ! MHD_EVENTS_PROCESS_H */