mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
Final part of external events
This commit is contained in:
@@ -1296,6 +1296,14 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
|
||||
*/
|
||||
MHD_SC_DAEMON_THREAD_STOP_UNEXPECTED = 50351
|
||||
,
|
||||
/**
|
||||
* Daemon system data is broken (like listen socket was unexpectedly closed).
|
||||
* The daemon needs to be closed.
|
||||
* A new daemon can be started as a replacement after closing the current
|
||||
* daemon.
|
||||
*/
|
||||
MHD_SC_DAEMON_SYS_DATA_BROKEN = 50370
|
||||
,
|
||||
/**
|
||||
* Failed to acquire response mutex lock
|
||||
*/
|
||||
@@ -1666,6 +1674,16 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
|
||||
* The Digest Auth is not supported due to configuration
|
||||
*/
|
||||
MHD_SC_AUTH_DIGEST_UNSUPPORTED = 60242
|
||||
,
|
||||
/**
|
||||
* The application failed to register FD for the external events monitoring
|
||||
*/
|
||||
MHD_SC_EXTR_EVENT_REG_FAILED = 60243
|
||||
,
|
||||
/**
|
||||
* The application failed to de-register FD for the external events monitoring
|
||||
*/
|
||||
MHD_SC_EXTR_EVENT_DEREG_FAILED = 60244
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -3923,6 +3941,13 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestEndedCode
|
||||
*/
|
||||
MHD_REQUEST_ENDED_BY_APP_ERROR = 41
|
||||
,
|
||||
/**
|
||||
* The request was aborted due to the application failed to register external
|
||||
* event monitoring for the connection.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_ENDED_BY_EXT_EVENT_ERROR = 42
|
||||
,
|
||||
/**
|
||||
* Error handling the connection due to resources exhausted.
|
||||
* @ingroup request
|
||||
|
||||
@@ -1296,6 +1296,14 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
|
||||
*/
|
||||
MHD_SC_DAEMON_THREAD_STOP_UNEXPECTED = 50351
|
||||
,
|
||||
/**
|
||||
* Daemon system data is broken (like listen socket was unexpectedly closed).
|
||||
* The daemon needs to be closed.
|
||||
* A new daemon can be started as a replacement after closing the current
|
||||
* daemon.
|
||||
*/
|
||||
MHD_SC_DAEMON_SYS_DATA_BROKEN = 50370
|
||||
,
|
||||
/**
|
||||
* Failed to acquire response mutex lock
|
||||
*/
|
||||
@@ -1666,6 +1674,16 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_StatusCode
|
||||
* The Digest Auth is not supported due to configuration
|
||||
*/
|
||||
MHD_SC_AUTH_DIGEST_UNSUPPORTED = 60242
|
||||
,
|
||||
/**
|
||||
* The application failed to register FD for the external events monitoring
|
||||
*/
|
||||
MHD_SC_EXTR_EVENT_REG_FAILED = 60243
|
||||
,
|
||||
/**
|
||||
* The application failed to de-register FD for the external events monitoring
|
||||
*/
|
||||
MHD_SC_EXTR_EVENT_DEREG_FAILED = 60244
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -3923,6 +3941,13 @@ enum MHD_FIXED_ENUM_MHD_SET_ MHD_RequestEndedCode
|
||||
*/
|
||||
MHD_REQUEST_ENDED_BY_APP_ERROR = 41
|
||||
,
|
||||
/**
|
||||
* The request was aborted due to the application failed to register external
|
||||
* event monitoring for the connection.
|
||||
* @ingroup request
|
||||
*/
|
||||
MHD_REQUEST_ENDED_BY_EXT_EVENT_ERROR = 42
|
||||
,
|
||||
/**
|
||||
* Error handling the connection due to resources exhausted.
|
||||
* @ingroup request
|
||||
|
||||
@@ -77,6 +77,7 @@ libmicrohttpd2_la_SOURCES = \
|
||||
daemon_get_info.c \
|
||||
daemon_add_conn.c daemon_add_conn.h \
|
||||
daemon_funcs.c daemon_funcs.h \
|
||||
daemon_event_update.c extr_events_funcs.c extr_events_funcs.h \
|
||||
conn_data_process.c conn_data_process.h \
|
||||
conn_data_recv.c conn_data_recv.h \
|
||||
conn_data_send.c conn_data_send.h \
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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/daemon_event_update.c
|
||||
* @brief The implementation of MHD_daemon_event_update() function for external
|
||||
* events updates
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "mhd_sys_options.h"
|
||||
|
||||
#include "sys_bool_type.h"
|
||||
|
||||
#include "mhd_assert.h"
|
||||
|
||||
#include "mhd_daemon.h"
|
||||
#include "mhd_connection.h"
|
||||
|
||||
#include "daemon_logger.h"
|
||||
|
||||
#include "mhd_public_api.h"
|
||||
|
||||
MHD_EXTERN_
|
||||
MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) void
|
||||
MHD_daemon_event_update (
|
||||
struct MHD_Daemon *MHD_RESTRICT daemon,
|
||||
struct MHD_EventUpdateContext *MHD_RESTRICT ecb_cntx,
|
||||
enum MHD_FdState fd_current_state)
|
||||
{
|
||||
bool broken_app_data;
|
||||
bool unneeded_event;
|
||||
|
||||
if (mhd_DAEMON_STATE_STARTED > daemon->state)
|
||||
return;
|
||||
if (! mhd_WM_INT_HAS_EXT_EVENTS (daemon->wmode_int))
|
||||
return; /* FIXME: log error? */
|
||||
if (mhd_DAEMON_STATE_STARTED < daemon->state)
|
||||
return;
|
||||
|
||||
broken_app_data = false;
|
||||
|
||||
switch ((mhd_SockRelMarker) ecb_cntx)
|
||||
{
|
||||
case mhd_SOCKET_REL_MARKER_EMPTY:
|
||||
broken_app_data = true;
|
||||
break;
|
||||
case mhd_SOCKET_REL_MARKER_ITC:
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (MHD_FD_STATE_IS_SET_EXCEPT (fd_current_state))
|
||||
daemon->events.data.extr.itc_data.is_broken = true;
|
||||
else
|
||||
{
|
||||
daemon->events.data.extr.itc_data.is_active =
|
||||
MHD_FD_STATE_IS_SET_RECV (fd_current_state);
|
||||
unneeded_event = MHD_FD_STATE_IS_SET_SEND (fd_current_state);
|
||||
}
|
||||
#else /* ! MHD_SUPPORT_THREADS */
|
||||
broken_app_data = true;
|
||||
#endif /* ! MHD_SUPPORT_THREADS */
|
||||
break;
|
||||
case mhd_SOCKET_REL_MARKER_LISTEN:
|
||||
if (MHD_INVALID_SOCKET == daemon->net.listen.fd)
|
||||
broken_app_data = true;
|
||||
else if (MHD_FD_STATE_IS_SET_EXCEPT (fd_current_state))
|
||||
daemon->net.listen.is_broken = true;
|
||||
else
|
||||
{
|
||||
daemon->events.accept_pending =
|
||||
MHD_FD_STATE_IS_SET_RECV (fd_current_state);
|
||||
unneeded_event = MHD_FD_STATE_IS_SET_SEND (fd_current_state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (((struct MHD_Connection *) ecb_cntx)->daemon != daemon)
|
||||
broken_app_data = true;
|
||||
else
|
||||
{
|
||||
struct MHD_Connection *const c = ((struct MHD_Connection *) ecb_cntx);
|
||||
unsigned int err_flag;
|
||||
|
||||
mhd_assert (MHD_FD_STATE_NONE != c->extr_event.reg_for);
|
||||
|
||||
unneeded_event = (0 != ((~((unsigned int) c->extr_event.reg_for))
|
||||
& ((unsigned int) fd_current_state)));
|
||||
|
||||
/* Preserve connection's "error flag" */
|
||||
err_flag = (((unsigned int) c->sk.ready)
|
||||
& (unsigned int) mhd_SOCKET_NET_STATE_ERROR_READY);
|
||||
|
||||
c->sk.ready =
|
||||
(enum mhd_SocketNetState)
|
||||
(err_flag | (((unsigned int) fd_current_state)
|
||||
& ((unsigned int) c->extr_event.reg_for)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (broken_app_data)
|
||||
{
|
||||
// TODO: log error
|
||||
(void) 0;
|
||||
}
|
||||
else if (unneeded_event)
|
||||
{
|
||||
// TODO: log error
|
||||
(void) 0;
|
||||
}
|
||||
}
|
||||
+79
-51
@@ -79,10 +79,11 @@
|
||||
# include "mhd_tls_funcs.h"
|
||||
#endif
|
||||
|
||||
#include "events_process.h"
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
# include "mhd_itc.h"
|
||||
# include "mhd_threads.h"
|
||||
# include "events_process.h"
|
||||
# include "daemon_funcs.h"
|
||||
#endif
|
||||
|
||||
@@ -1339,11 +1340,15 @@ daemon_choose_and_preinit_events (struct MHD_Daemon *restrict d,
|
||||
(MHD_WM_EXTERNAL_EVENT_LOOP_CB_EDGE == s->work_mode.mode));
|
||||
mhd_assert (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int));
|
||||
d->events.poll_type = mhd_POLL_TYPE_EXT;
|
||||
d->events.data.ext.cb_data.cb =
|
||||
d->events.data.extr.cb_data.cb =
|
||||
s->work_mode.params.v_external_event_loop_cb.reg_cb;
|
||||
d->events.data.ext.cb_data.cls =
|
||||
d->events.data.extr.cb_data.cls =
|
||||
s->work_mode.params.v_external_event_loop_cb.reg_cb_cls;
|
||||
d->events.data.ext.reg_all = (MHD_NO != s->reregister_all);
|
||||
d->events.data.extr.reg_all = (MHD_NO != s->reregister_all);
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
d->events.data.extr.itc_data.app_cntx = NULL;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
d->events.data.extr.listen_data.app_cntx = NULL;
|
||||
break;
|
||||
#ifdef MHD_SUPPORT_SELECT
|
||||
case mhd_POLL_TYPE_SELECT:
|
||||
@@ -1795,7 +1800,8 @@ allocate_events (struct MHD_Daemon *restrict d)
|
||||
switch (d->events.poll_type)
|
||||
{
|
||||
case mhd_POLL_TYPE_EXT:
|
||||
mhd_assert (NULL != d->events.data.ext.cb_data.cb);
|
||||
mhd_assert (NULL != d->events.data.extr.cb_data.cb);
|
||||
/* Nothing to do: allocation is not needed */
|
||||
#ifndef NDEBUG
|
||||
d->dbg.events_allocated = true;
|
||||
#endif
|
||||
@@ -2064,21 +2070,25 @@ init_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
|
||||
switch (d->events.poll_type)
|
||||
{
|
||||
case mhd_POLL_TYPE_EXT:
|
||||
mhd_assert (NULL != d->events.data.ext.cb_data.cb);
|
||||
if (! d->events.data.ext.reg_all)
|
||||
mhd_assert (NULL != d->events.data.extr.cb_data.cb);
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
d->events.data.extr.itc_data.is_active = false;
|
||||
d->events.data.extr.itc_data.is_broken = false;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
if (! d->events.data.extr.reg_all)
|
||||
{
|
||||
bool itc_reg_succeed;
|
||||
|
||||
/* Register daemon's FDs now */
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
d->events.data.ext.app_cntx.itc =
|
||||
d->events.data.ext.cb_data.cb (d->events.data.ext.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_RECV,
|
||||
NULL,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_ITC);
|
||||
itc_reg_succeed = (NULL != d->events.data.ext.app_cntx.itc);
|
||||
d->events.data.extr.itc_data.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_RECV_EXCEPT,
|
||||
NULL,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_ITC);
|
||||
itc_reg_succeed = (NULL != d->events.data.extr.itc_data.app_cntx);
|
||||
#else /* ! MHD_SUPPORT_THREADS */
|
||||
itc_reg_succeed = true;
|
||||
#endif /* ! MHD_SUPPORT_THREADS */
|
||||
@@ -2086,31 +2096,31 @@ init_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
if (MHD_INVALID_SOCKET == d->net.listen.fd)
|
||||
{
|
||||
d->events.data.ext.app_cntx.listen = NULL;
|
||||
d->events.data.extr.listen_data.app_cntx = NULL;
|
||||
return MHD_SC_OK; /* Success exit point */
|
||||
}
|
||||
|
||||
/* Need to register the listen FD */
|
||||
d->events.data.ext.app_cntx.listen =
|
||||
d->events.data.ext.cb_data.cb (d->events.data.ext.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_RECV,
|
||||
NULL,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
if (NULL != d->events.data.ext.app_cntx.listen)
|
||||
d->events.data.extr.listen_data.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_RECV_EXCEPT,
|
||||
NULL,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
if (NULL != d->events.data.extr.listen_data.app_cntx)
|
||||
return MHD_SC_OK; /* Success exit point */
|
||||
|
||||
/* Below is a clean-up path for 'case mhd_POLL_TYPE_EXT:' */
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
/* De-register ITC FD */
|
||||
(void) d->events.data.ext.cb_data.cb (d->events.data.ext.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.ext.app_cntx.itc,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_ITC);
|
||||
d->events.data.ext.app_cntx.itc = NULL;
|
||||
(void) d->events.data.extr.cb_data.cb (
|
||||
d->events.data.extr.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.extr.itc_data.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) mhd_SOCKET_REL_MARKER_ITC);
|
||||
d->events.data.extr.itc_data.app_cntx = NULL;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
}
|
||||
|
||||
@@ -2123,9 +2133,9 @@ init_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
/* Daemons FDs are repeatedly registered every processing cycle */
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
d->events.data.ext.app_cntx.itc = NULL;
|
||||
d->events.data.extr.itc_data.app_cntx = NULL;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
d->events.data.ext.app_cntx.listen = NULL;
|
||||
d->events.data.extr.listen_data.app_cntx = NULL;
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
break;
|
||||
@@ -2229,21 +2239,21 @@ deinit_daemon_fds_monitoring (struct MHD_Daemon *restrict d)
|
||||
switch (d->events.poll_type)
|
||||
{
|
||||
case mhd_POLL_TYPE_EXT:
|
||||
if (NULL != d->events.data.ext.app_cntx.listen)
|
||||
(void) d->events.data.ext.cb_data.cb (d->events.data.ext.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.ext.app_cntx.listen,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
if (NULL != d->events.data.extr.listen_data.app_cntx)
|
||||
(void) d->events.data.extr.cb_data.cb (
|
||||
d->events.data.extr.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.extr.listen_data.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (NULL != d->events.data.ext.app_cntx.itc)
|
||||
(void) d->events.data.ext.cb_data.cb (d->events.data.ext.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.ext.app_cntx.itc,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_ITC);
|
||||
if (NULL != d->events.data.extr.itc_data.app_cntx)
|
||||
(void) d->events.data.extr.cb_data.cb (
|
||||
d->events.data.extr.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.extr.itc_data.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) mhd_SOCKET_REL_MARKER_ITC);
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
return;
|
||||
#ifdef MHD_SUPPORT_SELECT
|
||||
@@ -2624,7 +2634,7 @@ set_d_threading_type (struct MHD_Daemon *restrict d)
|
||||
case mhd_WM_INT_EXTERNAL_EVENTS_LEVEL:
|
||||
mhd_assert (! mhd_WM_INT_HAS_THREADS (d->wmode_int));
|
||||
mhd_assert (mhd_POLL_TYPE_EXT == d->events.poll_type);
|
||||
mhd_assert (NULL != d->events.data.ext.cb_data.cb);
|
||||
mhd_assert (NULL != d->events.data.extr.cb_data.cb);
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
d->threading.d_type = mhd_DAEMON_TYPE_SINGLE;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
@@ -3183,9 +3193,7 @@ daemon_start_threads (struct MHD_Daemon *restrict d)
|
||||
|
||||
/**
|
||||
* Stop the daemon internal threads, if the daemon configured to use them.
|
||||
* @param d the daemon object, the threads (if any) must be started
|
||||
* @return #MHD_SC_OK on success,
|
||||
* the error code otherwise
|
||||
* @param d the daemon object to stop threads
|
||||
*/
|
||||
static MHD_FN_PAR_NONNULL_ (1) void
|
||||
daemon_stop_threads (struct MHD_Daemon *restrict d)
|
||||
@@ -3219,6 +3227,24 @@ daemon_stop_threads (struct MHD_Daemon *restrict d)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close all daemon connections for modes without internal threads
|
||||
* @param d the daemon object
|
||||
*/
|
||||
static MHD_FN_PAR_NONNULL_ (1) void
|
||||
daemon_close_connections (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
if (mhd_WM_INT_HAS_THREADS (d->wmode_int))
|
||||
{
|
||||
/* In these modes connections must be closed in the daemon thread */
|
||||
mhd_assert (NULL == mhd_DLINKEDL_GET_LAST (&(d->conns),all_conn));
|
||||
return;
|
||||
}
|
||||
|
||||
mhd_daemon_close_all_conns (d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal daemon initialisation function.
|
||||
* This function calls all required initialisation stages one-by-one.
|
||||
@@ -3333,6 +3359,8 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
|
||||
|
||||
daemon_stop_threads (daemon);
|
||||
|
||||
daemon_close_connections (daemon);
|
||||
|
||||
daemon_deinit_threading_and_conn (daemon);
|
||||
|
||||
daemon_deinit_large_buf (daemon);
|
||||
|
||||
+257
-4
@@ -57,6 +57,7 @@
|
||||
#include "daemon_funcs.h"
|
||||
#include "conn_data_process.h"
|
||||
#include "stream_funcs.h"
|
||||
#include "extr_events_funcs.h"
|
||||
|
||||
#ifdef MHD_SUPPORT_UPGRADE
|
||||
# include "upgrade_proc.h"
|
||||
@@ -373,8 +374,8 @@ daemon_cleanup_upgraded_conns (struct MHD_Daemon *d)
|
||||
#define daemon_cleanup_upgraded_conns(d) ((void) d)
|
||||
#endif /* ! MHD_SUPPORT_UPGRADE */
|
||||
|
||||
static void
|
||||
close_all_daemon_conns (struct MHD_Daemon *d)
|
||||
MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void
|
||||
mhd_daemon_close_all_conns (struct MHD_Daemon *d)
|
||||
{
|
||||
struct MHD_Connection *c;
|
||||
bool has_upgraded_unclosed;
|
||||
@@ -415,6 +416,198 @@ close_all_daemon_conns (struct MHD_Daemon *d)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process all external events updated of existing connections, information
|
||||
* about new connections pending to be accept()'ed, presence of the events on
|
||||
* the daemon's ITC.
|
||||
* @return 'true' if processed successfully,
|
||||
* 'false' is unrecoverable error occurs and the daemon must be
|
||||
* closed
|
||||
*/
|
||||
static MHD_FN_PAR_NONNULL_ (1) bool
|
||||
ext_events_process_net_updates (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
struct MHD_Connection *restrict c;
|
||||
|
||||
mhd_assert (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int));
|
||||
mhd_assert (mhd_POLL_TYPE_EXT == d->events.poll_type);
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (d->events.data.extr.itc_data.is_active)
|
||||
{
|
||||
d->events.data.extr.itc_data.is_active = false;
|
||||
/* Clear ITC here, before other data processing.
|
||||
* Any external events will activate ITC again if additional data to
|
||||
* process is added externally. Clearing ITC early ensures that new data
|
||||
* (with additional ITC activation) will not be missed. */
|
||||
mhd_itc_clear (d->threading.itc);
|
||||
}
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
for (c = mhd_DLINKEDL_GET_FIRST (&(d->conns),all_conn);
|
||||
NULL != c;
|
||||
c = mhd_DLINKEDL_GET_NEXT (c,all_conn))
|
||||
{
|
||||
bool has_err_state;
|
||||
if (is_conn_excluded_from_http_comm (c))
|
||||
continue;
|
||||
|
||||
has_err_state =
|
||||
(0 != (((unsigned int) c->sk.ready) & mhd_SOCKET_NET_STATE_ERROR_READY));
|
||||
|
||||
mhd_conn_mark_ready_update3 (c,
|
||||
has_err_state,
|
||||
d);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update all registrations of FDs for external monitoring.
|
||||
* @return #MHD_SC_OK on success,
|
||||
* error code otherwise
|
||||
*/
|
||||
static MHD_FN_PAR_NONNULL_ (1) enum MHD_StatusCode
|
||||
ext_events_update_registrations (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
const bool rereg_all = d->events.data.extr.reg_all;
|
||||
const bool edge_trigg = (mhd_WM_INT_EXTERNAL_EVENTS_EDGE == d->wmode_int);
|
||||
bool daemon_fds_succeed;
|
||||
struct MHD_Connection *c;
|
||||
struct MHD_Connection *c_next;
|
||||
|
||||
mhd_assert (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int));
|
||||
mhd_assert (mhd_POLL_TYPE_EXT == d->events.poll_type);
|
||||
|
||||
/* (Re-)register daemon's FDs */
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (rereg_all ||
|
||||
(NULL == d->events.data.extr.itc_data.app_cntx))
|
||||
{
|
||||
/* (Re-)register ITC FD */
|
||||
d->events.data.extr.itc_data.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
mhd_itc_r_fd (d->threading.itc),
|
||||
MHD_FD_STATE_RECV_EXCEPT,
|
||||
d->events.data.extr.itc_data.app_cntx,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_ITC);
|
||||
if (NULL != d->events.data.extr.itc_data.app_cntx)
|
||||
mhd_log_extr_event_dereg_failed (d);
|
||||
}
|
||||
daemon_fds_succeed = (NULL != d->events.data.extr.itc_data.app_cntx);
|
||||
#else /* ! MHD_SUPPORT_THREADS */
|
||||
daemon_fds_succeed = true;
|
||||
#endif /* ! MHD_SUPPORT_THREADS */
|
||||
|
||||
if (daemon_fds_succeed)
|
||||
{
|
||||
if ((MHD_INVALID_SOCKET == d->net.listen.fd) &&
|
||||
(NULL != d->events.data.extr.listen_data.app_cntx))
|
||||
{
|
||||
/* De-register the listen FD */
|
||||
d->events.data.extr.listen_data.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_NONE,
|
||||
d->events.data.extr.listen_data.app_cntx
|
||||
,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
if (NULL != d->events.data.extr.listen_data.app_cntx)
|
||||
mhd_log_extr_event_dereg_failed (d);
|
||||
}
|
||||
else if ((MHD_INVALID_SOCKET != d->net.listen.fd) &&
|
||||
(rereg_all || (NULL == d->events.data.extr.listen_data.app_cntx)))
|
||||
{
|
||||
/* (Re-)register listen FD */
|
||||
d->events.data.extr.listen_data.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
d->net.listen.fd,
|
||||
MHD_FD_STATE_RECV_EXCEPT,
|
||||
d->events.data.extr.listen_data.app_cntx
|
||||
,
|
||||
(struct MHD_EventUpdateContext *)
|
||||
mhd_SOCKET_REL_MARKER_LISTEN);
|
||||
|
||||
daemon_fds_succeed = (NULL != d->events.data.extr.listen_data.app_cntx);
|
||||
}
|
||||
}
|
||||
|
||||
if (! daemon_fds_succeed)
|
||||
{
|
||||
mhd_LOG_MSG (d, MHD_SC_EXT_EVENT_REG_DAEMON_FDS_FAILURE, \
|
||||
"Failed to register daemon FDs in the application "
|
||||
"(external events) monitoring.");
|
||||
return MHD_SC_EXT_EVENT_REG_DAEMON_FDS_FAILURE;
|
||||
}
|
||||
|
||||
for (c = mhd_DLINKEDL_GET_FIRST (&(d->conns),all_conn);
|
||||
NULL != c;
|
||||
c = c_next)
|
||||
{
|
||||
enum MHD_FdState watch_for;
|
||||
|
||||
/* Get the next connection now, as the current connection could be removed
|
||||
from the daemon. */
|
||||
c_next = mhd_DLINKEDL_GET_NEXT (c,all_conn);
|
||||
|
||||
if (is_conn_excluded_from_http_comm (c))
|
||||
{
|
||||
if (NULL != c->extr_event.app_cntx)
|
||||
{
|
||||
c->extr_event.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
c->sk.fd,
|
||||
MHD_FD_STATE_NONE,
|
||||
c->extr_event.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) c);
|
||||
if (NULL != c->extr_event.app_cntx)
|
||||
mhd_log_extr_event_dereg_failed (d);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
watch_for =
|
||||
edge_trigg ?
|
||||
MHD_FD_STATE_RECV_SEND_EXCEPT :
|
||||
(enum MHD_FdState) (MHD_FD_STATE_EXCEPT
|
||||
| (((unsigned int) c->event_loop_info)
|
||||
& (MHD_EVENT_LOOP_INFO_RECV
|
||||
| MHD_EVENT_LOOP_INFO_SEND)));
|
||||
|
||||
mhd_assert ((! edge_trigg) || \
|
||||
(MHD_FD_STATE_RECV_SEND_EXCEPT == c->extr_event.reg_for) || \
|
||||
(NULL == c->extr_event.app_cntx));
|
||||
|
||||
if ((NULL == c->extr_event.app_cntx) ||
|
||||
rereg_all ||
|
||||
(! edge_trigg && (watch_for != c->extr_event.reg_for)))
|
||||
{
|
||||
c->extr_event.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
c->sk.fd,
|
||||
watch_for,
|
||||
c->extr_event.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) c);
|
||||
if (NULL == c->extr_event.app_cntx)
|
||||
{
|
||||
mhd_conn_start_closing_ext_event_failed (c);
|
||||
mhd_conn_pre_clean (c);
|
||||
mhd_conn_remove_from_daemon (c);
|
||||
mhd_conn_close_final (c);
|
||||
}
|
||||
c->extr_event.reg_for = watch_for;
|
||||
}
|
||||
}
|
||||
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MHD_SUPPORT_SELECT
|
||||
|
||||
/**
|
||||
@@ -1147,7 +1340,9 @@ process_all_events_and_data (struct MHD_Daemon *restrict d)
|
||||
switch (d->events.poll_type)
|
||||
{
|
||||
case mhd_POLL_TYPE_EXT:
|
||||
return false; // TODO: implement
|
||||
mhd_assert (mhd_WM_INT_HAS_EXT_EVENTS (d->wmode_int));
|
||||
if (! ext_events_process_net_updates (d))
|
||||
return false;
|
||||
break;
|
||||
#ifdef MHD_SUPPORT_SELECT
|
||||
case mhd_POLL_TYPE_SELECT:
|
||||
@@ -1192,6 +1387,64 @@ process_all_events_and_data (struct MHD_Daemon *restrict d)
|
||||
}
|
||||
|
||||
|
||||
MHD_EXTERN_
|
||||
MHD_FN_PAR_NONNULL_ (1) enum MHD_StatusCode
|
||||
MHD_daemon_process_reg_events (struct MHD_Daemon *MHD_RESTRICT daemon,
|
||||
uint_fast64_t *MHD_RESTRICT next_max_wait)
|
||||
{
|
||||
enum MHD_StatusCode res;
|
||||
|
||||
if (mhd_DAEMON_STATE_STARTED > daemon->state)
|
||||
return MHD_SC_TOO_EARLY;
|
||||
if (! mhd_WM_INT_HAS_EXT_EVENTS (daemon->wmode_int))
|
||||
return MHD_SC_EXTERNAL_EVENT_ONLY;
|
||||
if (mhd_DAEMON_STATE_STARTED < daemon->state)
|
||||
return MHD_SC_TOO_LATE;
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (daemon->events.data.extr.itc_data.is_broken)
|
||||
return MHD_SC_DAEMON_SYS_DATA_BROKEN;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
if (daemon->net.listen.is_broken)
|
||||
return MHD_SC_DAEMON_SYS_DATA_BROKEN;
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (daemon->threading.resume_requested)
|
||||
mhd_daemon_resume_conns (daemon);
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
/* Ignore returned value */
|
||||
(void) process_all_events_and_data (daemon);
|
||||
|
||||
if (NULL != next_max_wait)
|
||||
*next_max_wait = MHD_WAIT_INDEFINITELY;
|
||||
|
||||
res = ext_events_update_registrations (daemon);
|
||||
if (MHD_SC_OK != res)
|
||||
return res;
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
if (daemon->events.data.extr.itc_data.is_broken)
|
||||
{
|
||||
log_itc_broken (daemon);
|
||||
return MHD_SC_DAEMON_SYS_DATA_BROKEN;
|
||||
}
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
if (daemon->net.listen.is_broken)
|
||||
{
|
||||
log_listen_broken (daemon);
|
||||
return MHD_SC_DAEMON_SYS_DATA_BROKEN;
|
||||
}
|
||||
|
||||
if (NULL != next_max_wait)
|
||||
*next_max_wait = mhd_daemon_get_wait_max ();
|
||||
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The entry point for the daemon worker thread
|
||||
* @param cls the closure
|
||||
@@ -1230,7 +1483,7 @@ mhd_worker_all_events (void *cls)
|
||||
"The daemon thread is stopping, but termination has not " \
|
||||
"been requested for the daemon.");
|
||||
}
|
||||
close_all_daemon_conns (d);
|
||||
mhd_daemon_close_all_conns (d);
|
||||
|
||||
return (mhd_THRD_RTRN_TYPE) 0;
|
||||
}
|
||||
|
||||
@@ -66,4 +66,13 @@ MHD_INTERNAL uint_fast64_t
|
||||
mhd_daemon_get_wait_max (struct MHD_Daemon *restrict d)
|
||||
MHD_FN_PAR_NONNULL_ALL_;
|
||||
|
||||
/**
|
||||
* Close all daemon connections.
|
||||
* Must not be called when any other connections processing function is running
|
||||
* @param d the daemon to use
|
||||
*/
|
||||
MHD_INTERNAL void
|
||||
mhd_daemon_close_all_conns (struct MHD_Daemon *d)
|
||||
MHD_FN_PAR_NONNULL_ALL_;
|
||||
|
||||
#endif /* ! MHD_EVENTS_PROCESS_H */
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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/extr_events_funcs.c
|
||||
* @brief The implementation of the external events internal helper functions
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "mhd_sys_options.h"
|
||||
#include "extr_events_funcs.h"
|
||||
|
||||
#ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
|
||||
|
||||
#include "daemon_logger.h"
|
||||
|
||||
MHD_INTERNAL void
|
||||
mhd_log_extr_event_dereg_failed (struct MHD_Daemon *restrict d)
|
||||
{
|
||||
mhd_LOG_MSG (d, \
|
||||
MHD_SC_EXTR_EVENT_DEREG_FAILED, \
|
||||
"Application failed to de-register FD: registration callback " \
|
||||
"returned non-NULL value");
|
||||
}
|
||||
|
||||
|
||||
#endif /* MHD_SUPPORT_LOG_FUNCTIONALITY */
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
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/extr_events_funcs.h
|
||||
* @brief The definition of the external events internal helper functions
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#ifndef MHD_EXTR_EVENTS_FUNCS_H
|
||||
#define MHD_EXTR_EVENTS_FUNCS_H 1
|
||||
|
||||
#include "mhd_sys_options.h"
|
||||
|
||||
#ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
|
||||
|
||||
struct MHD_Daemon; /* forward declaration */
|
||||
|
||||
/**
|
||||
* Log message about failed de-registration of FDs
|
||||
*/
|
||||
MHD_INTERNAL void
|
||||
mhd_log_extr_event_dereg_failed (struct MHD_Daemon *restrict d);
|
||||
|
||||
#else /* ! MHD_SUPPORT_LOG_FUNCTIONALITY */
|
||||
|
||||
/**
|
||||
* Log message about failed de-registration of FDs (no-op implementation)
|
||||
*/
|
||||
#define mhd_log_extr_event_dereg_failed(d) ((void) 0)
|
||||
|
||||
#endif /* ! MHD_SUPPORT_LOG_FUNCTIONALITY */
|
||||
|
||||
#endif /* ! MHD_EXTR_EVENTS_FUNCS_H */
|
||||
@@ -456,6 +456,24 @@ enum MHD_FIXED_ENUM_ mhd_HttpStage
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The connection's external event data
|
||||
*/
|
||||
struct mhd_ConnExtrEvents
|
||||
{
|
||||
/**
|
||||
* Connection's application context for the external events monitoring
|
||||
*/
|
||||
void *app_cntx;
|
||||
|
||||
/**
|
||||
* The last targets for which the connection FD has been registration for
|
||||
*/
|
||||
enum MHD_FdState reg_for;
|
||||
};
|
||||
|
||||
|
||||
struct mhd_ConnDebugData
|
||||
{
|
||||
bool closing_started;
|
||||
@@ -506,6 +524,11 @@ struct MHD_Connection
|
||||
*/
|
||||
struct mhd_ConnSocket sk;
|
||||
|
||||
/**
|
||||
* The connection's external event data
|
||||
*/
|
||||
struct mhd_ConnExtrEvents extr_event;
|
||||
|
||||
#ifdef MHD_SUPPORT_HTTPS
|
||||
/**
|
||||
* Connection-specific TLS data.
|
||||
|
||||
+38
-12
@@ -332,22 +332,41 @@ struct mhd_DaemonEventsExternalCallback
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Application context for external events for daemon's FDs
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalScktAppCntx
|
||||
{
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
/**
|
||||
* External events data for ITC FD
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalDaemonItcData
|
||||
{
|
||||
/**
|
||||
* Application context for ITC FD
|
||||
*/
|
||||
void *itc;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
void *app_cntx;
|
||||
|
||||
/**
|
||||
* Application context for listen socket
|
||||
* Set to 'true' when active state was detected on ITC by
|
||||
* external polling
|
||||
*/
|
||||
void *listen;
|
||||
bool is_active;
|
||||
|
||||
/**
|
||||
* Set to 'true' when error state was detected on ITC by
|
||||
* external polling.
|
||||
* The daemon may become non-functional.
|
||||
*/
|
||||
bool is_broken;
|
||||
};
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
/**
|
||||
* External events data for the listen socket
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalDaemonListenData
|
||||
{
|
||||
/**
|
||||
* Application context for ITC FD
|
||||
*/
|
||||
void *app_cntx;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -361,10 +380,17 @@ struct mhd_DaemonEventsExternal
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalCallback cb_data;
|
||||
|
||||
#ifdef MHD_SUPPORT_THREADS
|
||||
/**
|
||||
* Application context for external events for daemon's FDs
|
||||
* External events data for ITC FD
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalScktAppCntx app_cntx;
|
||||
struct mhd_DaemonEventsExternalDaemonItcData itc_data;
|
||||
#endif /* MHD_SUPPORT_THREADS */
|
||||
|
||||
/**
|
||||
* External events data for the listen socket
|
||||
*/
|
||||
struct mhd_DaemonEventsExternalDaemonListenData listen_data;
|
||||
|
||||
/**
|
||||
* If set to 'true' then all FDs must be registered each round.
|
||||
@@ -405,7 +431,7 @@ union mhd_DaemonEventMonitoringTypeSpecificData
|
||||
/**
|
||||
* Daemon's data for external events for sockets monitoring.
|
||||
*/
|
||||
struct mhd_DaemonEventsExternal ext;
|
||||
struct mhd_DaemonEventsExternal extr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+22
-1
@@ -53,6 +53,7 @@
|
||||
#include "daemon_funcs.h"
|
||||
#include "conn_mark_ready.h"
|
||||
#include "stream_process_reply.h"
|
||||
#include "extr_events_funcs.h"
|
||||
|
||||
#ifdef MHD_SUPPORT_HTTPS
|
||||
# include "mhd_tls_funcs.h"
|
||||
@@ -750,6 +751,11 @@ mhd_conn_start_closing (struct MHD_Connection *restrict c,
|
||||
close_hard = true;
|
||||
end_code = MHD_REQUEST_ENDED_NO_RESOURCES;
|
||||
break;
|
||||
case mhd_CONN_CLOSE_EXTR_EVENT_REG_FAILED:
|
||||
close_hard = true;
|
||||
end_code = MHD_REQUEST_ENDED_BY_EXT_EVENT_ERROR;
|
||||
sc = MHD_SC_EXTR_EVENT_REG_FAILED;
|
||||
break;
|
||||
case mhd_CONN_CLOSE_NO_SYS_RESOURCES:
|
||||
close_hard = true;
|
||||
end_code = MHD_REQUEST_ENDED_NO_RESOURCES;
|
||||
@@ -941,8 +947,23 @@ mhd_conn_pre_clean_part1 (struct MHD_Connection *restrict c)
|
||||
if (NULL != c->rq.cntn.lbuf.data)
|
||||
mhd_daemon_free_lbuf (c->daemon, &(c->rq.cntn.lbuf));
|
||||
|
||||
if (mhd_WM_INT_HAS_EXT_EVENTS (c->daemon->wmode_int))
|
||||
{
|
||||
struct MHD_Daemon *const d = c->daemon;
|
||||
if (NULL != c->extr_event.app_cntx)
|
||||
{
|
||||
c->extr_event.app_cntx =
|
||||
d->events.data.extr.cb_data.cb (d->events.data.extr.cb_data.cls,
|
||||
c->sk.fd,
|
||||
MHD_FD_STATE_NONE,
|
||||
c->extr_event.app_cntx,
|
||||
(struct MHD_EventUpdateContext *) c);
|
||||
if (NULL != c->extr_event.app_cntx)
|
||||
mhd_log_extr_event_dereg_failed (d);
|
||||
}
|
||||
}
|
||||
#ifdef MHD_SUPPORT_EPOLL
|
||||
if (mhd_POLL_TYPE_EPOLL == c->daemon->events.poll_type)
|
||||
else if (mhd_POLL_TYPE_EPOLL == c->daemon->events.poll_type)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
|
||||
@@ -228,6 +228,11 @@ enum mhd_ConnCloseReason
|
||||
*/
|
||||
mhd_CONN_CLOSE_INT_ERROR
|
||||
,
|
||||
/**
|
||||
* Failed to register the connection for the external event monitoring
|
||||
*/
|
||||
mhd_CONN_CLOSE_EXTR_EVENT_REG_FAILED
|
||||
,
|
||||
/**
|
||||
* No system resources available to handle connection
|
||||
*/
|
||||
@@ -321,6 +326,29 @@ MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (3);
|
||||
#define mhd_conn_start_closing_app_abort(c) \
|
||||
mhd_conn_start_closing ((c), mhd_CONN_CLOSE_APP_ABORTED, NULL)
|
||||
|
||||
|
||||
#ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
|
||||
/**
|
||||
* Perform initial clean-up and mark for closing.
|
||||
* Set the reason to "socket error"
|
||||
* @param c the connection for pre-closing
|
||||
*/
|
||||
#define mhd_conn_start_closing_ext_event_failed(c) \
|
||||
mhd_conn_start_closing ((c), \
|
||||
mhd_CONN_CLOSE_EXTR_EVENT_REG_FAILED, \
|
||||
"The application failed to register FD for " \
|
||||
"the external events monitoring.")
|
||||
#else /* ! MHD_SUPPORT_LOG_FUNCTIONALITY */
|
||||
/**
|
||||
* Perform initial clean-up and mark for closing.
|
||||
* Set the reason to "socket error"
|
||||
* @param c the connection for pre-closing
|
||||
*/
|
||||
#define mhd_conn_start_closing_ext_event_failed(c) \
|
||||
mhd_conn_start_closing ((c), \
|
||||
mhd_CONN_CLOSE_EXTR_EVENT_REG_FAILED, NULL)
|
||||
#endif /* ! MHD_SUPPORT_LOG_FUNCTIONALITY */
|
||||
|
||||
/**
|
||||
* Perform initial clean-up and mark for closing.
|
||||
* Set the reason to "socket error"
|
||||
|
||||
Reference in New Issue
Block a user