Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event wip #294

Open
wants to merge 22 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d865e09
core: Change filter input/output pending API to return OK/AGAIN/DONE.
ylavic Jun 23, 2023
a92dd49
mpm_event,listen: Improve/fix children maintenance when num_buckets > 1.
ylavic Jul 11, 2023
b85d738
mpm_event: Add helpers, simplify code and improve logging before func…
ylavic Jun 3, 2024
db8ec1e
mpm_event: Use monotonic timestamps if available.
ylavic Feb 1, 2022
8f3ed4c
mpm_event: No need/use of "clogged" connections count, axe.
ylavic Jul 9, 2024
f1367ba
mpm_event: Use r->server's Timeout after the post_read_request hook.
ylavic Feb 1, 2022
589d21a
mpm_event: Add kill_connection() to log (APLOG_INFO) interrupted conn…
ylavic Jun 27, 2023
0ea6ae6
core,mod_reqtimeout: Add ap_get_connection_timeout().
ylavic Feb 1, 2022
8bddc07
mpm_event: Use ap_get_connection_timeout() for CONN_STATE_ASYNC_WAITIO.
ylavic Feb 1, 2022
ae9a3b9
mpm_fdqueue: Allow to queue any events (socket, timer, opaque), and u…
ylavic Jun 3, 2024
aa04f2a
core,mpm_event: Non blocking shutdown.
ylavic Jul 7, 2023
364a389
mpm_event: Don't shrink keepalive queue when busy/exiting.
ylavic Jul 10, 2024
eb1eb7f
mpm_event: Single linger queue/timeout (short one, 2s).
ylavic Jun 26, 2023
c82d67a
mpm_event: Periodic linger queue shrink (500ms).
ylavic Jun 26, 2023
eddf299
mpm_event: Use atomic reads/writes for shared resources.
ylavic Jun 26, 2023
143a83e
mpm_event: Periodic scoreboard stats update (1s).
ylavic Jun 3, 2024
fccc162
mpm_event: Autotuning from MaxRequestWorkers.
ylavic Jun 27, 2023
fb88393
mpm_event: Propose some new connections_above_limit() heuristics.
ylavic Jul 10, 2024
94baa05
mod_ssl: Nonblocking/async handshakes in CONN_STATE_PROCESSING phase.
ylavic Jul 8, 2024
6cbda1f
core,http: Non blocking HTTP header read.
ylavic Jul 9, 2024
6eee3f3
mod_proxy,mpm_event: Replace ap_mpm_register_poll_callback*() by ap_m…
ylavic Jul 11, 2024
92d0cdd
mod_status: Be less racy, improve rendering, and show suspended conne…
ylavic Jun 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes-entries/mod_ssl_async_handshakes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*) mod_ssl: Perform non blocking and async TLS handshakes. [Graham Leggett]
5 changes: 5 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ AC_CHECK_HEADERS( \
string.h \
limits.h \
unistd.h \
time.h \
mach/mach_time.h \
sys/socket.h \
pwd.h \
grp.h \
Expand Down Expand Up @@ -534,6 +536,9 @@ getpwnam \
getgrnam \
initgroups \
bindprocessor \
clock_getres \
clock_gettime \
clock_gettime_nsec_np \
prctl \
procctl \
pthread_getthreadid_np \
Expand Down
12 changes: 10 additions & 2 deletions include/ap_mmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -731,14 +731,22 @@
* and AP_REQUEST_TRUSTED_CT BNOTE.
* 20211221.24 (2.5.1-dev) Add ap_proxy_fixup_uds_filename()
* 20211221.25 (2.5.1-dev) AP_SLASHES and AP_IS_SLASH
* 20211221.26 (2.5.1-dev) Add AGAIN, ap_check_input_pending() and
* ap_check_output_pending()
* 20211221.27 (2.5.1-dev) Add min_connection_timeout hook and
* ap_get_connection_timeout()
* 20211221.28 (2.5.1-dev) Add ap_mpm_poll_suspended() and
* AP_MPMQ_CAN_POLL_SUSPENDED
* 20240701.0 (2.5.1-dev) Axe ap_mpm_register_poll_callback and
* ap_mpm_register_poll_callback_timeout
*/

#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */

#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20211221
#define MODULE_MAGIC_NUMBER_MAJOR 20240701
#endif
#define MODULE_MAGIC_NUMBER_MINOR 25 /* 0...n */
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */

/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Expand Down
51 changes: 6 additions & 45 deletions include/ap_mpm.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process(
#define AP_MPMQ_CAN_POLL 18
/** MPM supports CONN_STATE_ASYNC_WAITIO */
#define AP_MPMQ_CAN_WAITIO 19
/** MPM implements the poll_suspended hook */
#define AP_MPMQ_CAN_POLL_SUSPENDED 20
/** @} */

/**
Expand All @@ -206,54 +208,13 @@ typedef void (ap_mpm_callback_fn_t)(void *baton);
/* only added support in the Event MPM.... check for APR_ENOTIMPL */
AP_DECLARE(apr_status_t) ap_mpm_resume_suspended(conn_rec *c);
/* only added support in the Event MPM.... check for APR_ENOTIMPL */
AP_DECLARE(apr_status_t) ap_mpm_poll_suspended(conn_rec *c, apr_pool_t *p,
const apr_array_header_t *pfds,
apr_interval_time_t timeout);
/* only added support in the Event MPM.... check for APR_ENOTIMPL */
AP_DECLARE(apr_status_t) ap_mpm_register_timed_callback(
apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton);

/**
* Register a callback on the readability or writability on a group of
* sockets/pipes.
* @param p Pool used by the MPM for its internal allocations
* @param pfds Array of apr_pollfd_t
* @param cbfn The callback function
* @param baton userdata for the callback function
* @return APR_SUCCESS if all sockets/pipes could be added to a pollset,
* APR_ENOTIMPL if no asynch support, or an apr_pollset_add error.
* @remark When activity is found on any 1 socket/pipe in the list, all are removed
* from the pollset and only 1 callback is issued.
* @remark The passed in pool can be cleared by cbfn and tofn when called back,
* it retains no MPM persistent data and won't be used until the next call
* to ap_mpm_register_poll_callback[_timeout].
*/

AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback(
apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, void *baton);

/**
* Register a callback on the readability or writability on a group of sockets/pipes,
* with a timeout.
* @param p Pool used by the MPM for its internal allocations
* @param pfds Array of apr_pollfd_t
* @param cbfn The callback function
* @param tofn The callback function if the timeout expires
* @param baton userdata for the callback function
* @param timeout timeout for I/O in microseconds, unlimited if <= 0
* @return APR_SUCCESS if all sockets/pipes could be added to a pollset,
* APR_ENOTIMPL if no asynch support, or an apr_pollset_add error.
* @remark When activity is found on any 1 socket/pipe in the list, all are removed
* from the pollset and only 1 callback is issued.
* @remark For each call, only one of tofn or cbfn will be called, never both.
* @remark The passed in pool can be cleared by cbfn and tofn when called back,
* it retains no MPM persistent data and won't be used until the next call
* to ap_mpm_register_poll_callback[_timeout].
*/

AP_DECLARE(apr_status_t) ap_mpm_register_poll_callback_timeout(
apr_pool_t *p, const apr_array_header_t *pfds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout);


typedef enum mpm_child_status {
MPM_CHILD_STARTED,
MPM_CHILD_EXITED,
Expand Down
14 changes: 12 additions & 2 deletions include/http_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,23 @@ extern "C" {
*/
AP_CORE_DECLARE(void) ap_process_connection(conn_rec *c, void *csd);

#define AP_SHUTDOWN_CONN_NOFLUSH 0
#define AP_SHUTDOWN_CONN_FLUSH 1
#define AP_SHUTDOWN_CONN_WC 2

/**
* Shutdown the connection for writing.
* @param c The connection to shutdown
* @param flush Whether or not to flush pending data before
* @param flush Whether to flush pending data before, and if so how to
* (AP_SHUTDOWN_CONN_* flags)
* @return APR_SUCCESS or the underlying error
*/
AP_CORE_DECLARE(apr_status_t) ap_shutdown_conn(conn_rec *c, int flush);

/**
* Flushes all remain data in the client send buffer
* @param c The connection to flush
* @remark calls ap_shutdown_conn(c, 1)
* @remark calls ap_shutdown_conn(c, AP_SHUTDOWN_CONN_FLUSH)
*/
AP_CORE_DECLARE(void) ap_flush_conn(conn_rec *c);

Expand Down Expand Up @@ -196,6 +201,11 @@ AP_DECLARE(conn_rec *) ap_create_secondary_connection(apr_pool_t *pool,
conn_rec *master,
apr_bucket_alloc_t *alloc);

AP_DECLARE_HOOK(int, min_connection_timeout,
(conn_rec *c, server_rec *s, apr_interval_time_t *min_timeout))

AP_DECLARE(apr_interval_time_t) ap_get_connection_timeout(conn_rec *c,
server_rec *s);

/** End Of Connection (EOC) bucket */
AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_eoc;
Expand Down
75 changes: 68 additions & 7 deletions include/http_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,30 @@ AP_DECLARE_DATA extern ap_filter_rec_t *ap_old_write_func;
*/

/**
* Read an empty request and set reasonable defaults.
* Create an empty request and set reasonable defaults.
* @param c The current connection
* @return The new request_rec
*/
AP_DECLARE(request_rec *) ap_create_request(conn_rec *c);

/**
* Read a request and fill in the fields.
* Read the request line and header fields.
* @param c The current connection
* @return The new request_rec
*/
AP_DECLARE(request_rec *) ap_read_request(conn_rec *c);

/**
* Read the request line and header fields, possibly non-blocking.
* @param r The request read
* @param c The connection to read from
* @param block How the read should be performed
* ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
* @return APR_SUCCESS, APR_EAGAIN or APR_EGENERAL
*/
AP_DECLARE(apr_status_t) ap_read_request_ex(request_rec **r, conn_rec *c,
apr_read_type_e block);

/**
* Assign the method, uri and protocol (in HTTP/1.x the
* items from the first line) to the request.
Expand Down Expand Up @@ -107,6 +118,12 @@ AP_DECLARE(int) ap_parse_request_line(request_rec *r);
*/
AP_DECLARE(int) ap_check_request_header(request_rec *r);

/**
* Reentrant state for ap_fgetline_ex() and ap_get_mime_headers_ex()
*/
struct ap_getline_state; /* opaque */
typedef struct ap_getline_state ap_getline_state_t;

/**
* Read the mime-encoded headers.
* @param r The current request
Expand All @@ -122,6 +139,23 @@ AP_DECLARE(void) ap_get_mime_headers(request_rec *r);
AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r,
apr_bucket_brigade *bb);

/**
* Reentrant version of ap_get_mime_headers() reading from an input
* filter in blocking or non-blocking mode.
* @param r The current request
* @param f Input filter to read from
* @param block How the operations should be performed
* ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
* @param bb temp brigade
* @param state_p State of the parsing, must point to NULL on first call
* and points to NULL on output if APR_EAGAIN is not returned
*/
AP_DECLARE(apr_status_t) ap_get_mime_headers_ex(request_rec *r,
ap_filter_t *f,
apr_read_type_e block,
apr_bucket_brigade *bb,
ap_getline_state_t **state_p);

/**
* Run post_read_request hook and validate.
* @param r The current request
Expand Down Expand Up @@ -744,11 +778,13 @@ AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r,
*/
AP_CORE_DECLARE(void) ap_parse_uri(request_rec *r, const char *uri);

#define AP_GETLINE_FOLD (1 << 0) /* Whether to merge continuation lines */
#define AP_GETLINE_CRLF (1 << 1) /* Whether line ends must be CRLF */
#define AP_GETLINE_NOSPC_EOL (1 << 2) /* Whether to consume up to and including
the end of line on APR_ENOSPC */
#define AP_GETLINE_NONBLOCK (1 << 3) /* Whether to read non-blocking */
#define AP_GETLINE_FOLD (1 << 0) /* Whether to merge continuation lines */
#define AP_GETLINE_CRLF (1 << 1) /* Whether line ends must be CRLF */
#define AP_GETLINE_NOSPC_EOL (1 << 2) /* Whether to consume up to and including
the end of line on APR_ENOSPC */
#define AP_GETLINE_NONBLOCK (1 << 3) /* Whether to read non-blocking */
#define AP_GETLINE_ALLOC (1 << 4) /* Whether to allocate the returned line */
#define AP_GETLINE_FOLD_COL (1 << 5 | AP_GETLINE_FOLD) /* Fold after colon only */

/**
* Get the next line of input for the request
Expand Down Expand Up @@ -783,6 +819,31 @@ AP_DECLARE(apr_status_t) ap_fgetline(char **s, apr_size_t n,
int flags, apr_bucket_brigade *bb,
apr_pool_t *p);

/**
* Get the next line from an input filter, reentrant (e.g. EAGAIN).
*
* @param s Pointer to the pointer to the buffer into which the line
* should be read; if *s==NULL, a buffer of the necessary size
* to hold the data will be allocated from \p p
* @param n The size of the buffer
* @param read The length of the line.
* @param f Input filter to read from
* @param flags Bit mask of AP_GETLINE_* options
* @param bb Working brigade to use when reading buckets
* @param state_p State of the parsing, must point to NULL on first call
* and points to NULL on output if APR_EAGAIN is not returned
* @param p The pool to allocate the buffer from (if needed)
* @return APR_SUCCESS, if successful
* APR_ENOSPC, if the line is too big to fit in the buffer
* APR_EAGAIN, if non-blocking IO would block
* Other errors where appropriate
*/
AP_DECLARE(apr_status_t) ap_fgetline_ex(char **s, apr_size_t n,
apr_size_t *read, ap_filter_t *f,
int flags, apr_bucket_brigade *bb,
ap_getline_state_t **state_p,
apr_pool_t *p);

/**
* @see ap_fgetline
*
Expand Down
7 changes: 6 additions & 1 deletion include/httpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ AP_DECLARE(const char *) ap_get_server_built(void);
*/
#define SUSPENDED -3 /**< Module will handle the remainder of the request.
* The core will never invoke the request again */
#define AGAIN -4 /**< Module wants to be called again when
* more data is availble */

/** Returned by the bottom-most filter if no data was written.
* @see ap_pass_brigade(). */
Expand Down Expand Up @@ -1313,6 +1315,9 @@ struct conn_rec {
int async_filter;

int outgoing;

/** Partial request being read (non-blocking) */
request_rec *partial_request;
};

struct conn_slave_rec {
Expand All @@ -1329,7 +1334,7 @@ typedef enum {
CONN_STATE_PROCESSING, /* Processed by process_connection hooks */
CONN_STATE_HANDLER, /* Processed by the modules handlers */
CONN_STATE_WRITE_COMPLETION, /* Flushed by the MPM before entering CONN_STATE_KEEPALIVE */
CONN_STATE_SUSPENDED, /* Suspended in the MPM until ap_run_resume_suspended() */
CONN_STATE_SUSPENDED, /* Suspended from the MPM until ap_run_resume_suspended() */
CONN_STATE_LINGER, /* MPM flushes then closes the connection with lingering */
CONN_STATE_LINGER_NORMAL, /* MPM has started lingering close with normal timeout */
CONN_STATE_LINGER_SHORT, /* MPM has started lingering close with short timeout */
Expand Down
8 changes: 4 additions & 4 deletions include/mod_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ extern "C" {

/* Handles for core filters */
AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_input_filter_handle;
AP_DECLARE_DATA extern ap_filter_rec_t *ap_h1_request_in_filter_handle;
AP_DECLARE_DATA extern ap_filter_rec_t *ap_h1_header_in_filter_handle;
AP_DECLARE_DATA extern ap_filter_rec_t *ap_h1_body_in_filter_handle;
AP_DECLARE_DATA extern ap_filter_rec_t *ap_http_header_filter_handle;
AP_DECLARE_DATA extern ap_filter_rec_t *ap_chunk_filter_handle;
Expand All @@ -55,9 +55,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t readbytes);

apr_status_t ap_h1_request_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t readbytes);
apr_status_t ap_h1_header_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
ap_input_mode_t mode, apr_read_type_e block,
apr_off_t readbytes);

apr_status_t ap_h1_body_in_filter(ap_filter_t *f, apr_bucket_brigade *b,
ap_input_mode_t mode, apr_read_type_e block,
Expand Down
36 changes: 4 additions & 32 deletions include/mpm_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,22 +422,12 @@ AP_DECLARE_HOOK(int, mpm_query, (int query_code, int *result, apr_status_t *rv))
AP_DECLARE_HOOK(apr_status_t, mpm_register_timed_callback,
(apr_time_t t, ap_mpm_callback_fn_t *cbfn, void *baton))

/**
* register the specified callback
* @ingroup hooks
*/
AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback,
(apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, void *baton))

/* register the specified callback, with timeout
/** Put suspended connection's pollfds into the MPM's pollset
* @ingroup hooks
*
*/
AP_DECLARE_HOOK(apr_status_t, mpm_register_poll_callback_timeout,
(apr_pool_t *p, const apr_array_header_t *pds,
ap_mpm_callback_fn_t *cbfn, ap_mpm_callback_fn_t *tofn,
void *baton, apr_time_t timeout))
AP_DECLARE_HOOK(apr_status_t, mpm_poll_suspended,
(conn_rec *c, apr_pool_t *p, const apr_array_header_t *pfds,
apr_interval_time_t timeout))

/** Resume the suspended connection
* @ingroup hooks
Expand All @@ -450,24 +440,6 @@ AP_DECLARE_HOOK(apr_status_t, mpm_resume_suspended, (conn_rec*))
*/
AP_DECLARE_HOOK(const char *,mpm_get_name,(void))

/**
* Hook called to determine whether we should stay within the write completion
* phase.
* @param c The current connection
* @return OK if write completion should continue, DECLINED if write completion
* should end gracefully, or a positive error if we should begin to linger.
* @ingroup hooks
*/
AP_DECLARE_HOOK(int, output_pending, (conn_rec *c))

/**
* Hook called to determine whether any data is pending in the input filters.
* @param c The current connection
* @return OK if we can read without blocking, DECLINED if a read would block.
* @ingroup hooks
*/
AP_DECLARE_HOOK(int, input_pending, (conn_rec *c))

/**
* Notification that connection handling is suspending (disassociating from the
* current thread)
Expand Down
2 changes: 2 additions & 0 deletions include/scoreboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ struct process_score {
apr_uint32_t keep_alive; /* async connections in keep alive */
apr_uint32_t suspended; /* connections suspended by some module */
apr_uint32_t wait_io; /* async connections waiting an IO in the MPM */
apr_uint32_t shutdown; /* async connections shutting down before close */
apr_uint32_t backlog; /* async connections waiting for a worker */
};

/* Scoreboard is now in 'local' memory, since it isn't updated once created,
Expand Down
Loading
Loading