MHD_daemon_get_info_dynamic_sz(): implemented

This commit is contained in:
Evgeny Grin (Karlson2k)
2025-01-15 19:11:13 +01:00
parent 4b3d47cca7
commit de741e6926
5 changed files with 187 additions and 56 deletions
+44 -26
View File
@@ -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 * */
/**
@@ -9353,16 +9351,16 @@ enum MHD_DaemonInfoDynamicType
*/
union MHD_DaemonInfoDynamicData
{
/**
* The boolean value
*/
enum MHD_Bool v_bool;
/**
* Unsigned 64 bits integer value.
*/
uint_fast64_t v_uint64;
/**
* Unsigned integer value.
*/
unsigned int v_uint;
/**
* Unused member.
* Help enforcing future-proof alignment of the union.
@@ -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)))
/**
+44 -26
View File
@@ -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 * */
/**
@@ -4731,16 +4729,16 @@ enum MHD_DaemonInfoDynamicType
*/
union MHD_DaemonInfoDynamicData
{
/**
* The boolean value
*/
enum MHD_Bool v_bool;
/**
* Unsigned 64 bits integer value.
*/
uint_fast64_t v_uint64;
/**
* Unsigned integer value.
*/
unsigned int v_uint;
/**
* Unused member.
* Help enforcing future-proof alignment of the union.
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */