Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.1

*) mpm_event: Add optional hooks for modules that manage connections
outside the MPM accept loop (UDP connections) can be accounted for.
[Tarek Ibrahim <tareki pulsarxtech.com> <t1br4h1m gmail.com>]

*) mpm_event: Avoid crashes in setup_slave_conn() when handling
connections not managed by the MPM.
[Tarek Ibrahim <tareki pulsarxtech.com> <t1br4h1m gmail.com>]

* mod_ssl: Add support for OpenSSL provider based certificate
stores. [Graham Leggett]

Expand Down
15 changes: 15 additions & 0 deletions include/mpm_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "ap_config.h"
#include "ap_mpm.h"
#include "scoreboard.h"
#include "apr_optional.h"

#if APR_HAVE_NETINET_TCP_H
#include <netinet/tcp.h> /* for TCP_NODELAY */
Expand Down Expand Up @@ -560,6 +561,20 @@ AP_DECLARE_HOOK(void, child_stopped,
*/
void mpm_common_pre_config(apr_pool_t *pconf);

/**
* Hooks for modules to report connections the MPM did not accept itself.
*
* MPMs that wait for their connection count to drain before stopping a child
* need this so externally accepted connections keep the child alive until
* they finish.
*
* Call ap_mpm_note_extra_connection_added() when such a connection starts,
* and ap_mpm_note_extra_connection_removed() when it ends. These functions
* may be NULL if the active MPM does not implement them.
*/
APR_DECLARE_OPTIONAL_FN(void, ap_mpm_note_extra_connection_added, (void));
APR_DECLARE_OPTIONAL_FN(void, ap_mpm_note_extra_connection_removed, (void));

#ifdef __cplusplus
}
#endif
Expand Down
22 changes: 22 additions & 0 deletions server/mpm/event/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,21 @@ static apr_status_t decrement_connection_count(void *cs_)
return APR_SUCCESS;
}

static void ap_mpm_note_extra_connection_added(void)
{
apr_atomic_inc32(&connection_count);
}

static void ap_mpm_note_extra_connection_removed(void)
{
int is_last_connection = !apr_atomic_dec32(&connection_count);

/* Wake a listener blocked waiting for connection_count to drain. */
if (listener_is_wakeable && is_last_connection && listener_may_exit) {
apr_pollset_wakeup(event_pollset);
}
}

static void notify_suspend(event_conn_state_t *cs)
{
ap_run_suspend_connection(cs->c, cs->r);
Expand Down Expand Up @@ -3876,6 +3891,10 @@ static void setup_slave_conn(conn_rec *c, void *csd)
event_conn_state_t *cs;

mcs = ap_get_module_config(c->master->conn_config, &mpm_event_module);
if (!mcs) {
/* Master connection is not managed by this MPM; nothing to inherit. */
return;
}

cs = apr_pcalloc(c->pool, sizeof(*cs));
cs->c = c;
Expand Down Expand Up @@ -3954,6 +3973,9 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
const char *userdata_key = "mpm_event_module";
int test_atomics = 0;

APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_added);
APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_removed);

debug = ap_exists_config_define("DEBUG");

if (debug) {
Expand Down
20 changes: 20 additions & 0 deletions server/mpm/prefork/prefork.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "apr_portable.h"
#include "apr_strings.h"
#include "apr_thread_proc.h"
#include "apr_atomic.h"
#include "apr_signal.h"

#define APR_WANT_STDIO
Expand Down Expand Up @@ -89,6 +90,7 @@

/* config globals */

static apr_uint32_t connection_count = 0; /* Number of open connections */
static int ap_daemons_to_start=0;
static int ap_daemons_min_free=0;
static int ap_daemons_max_free=0;
Expand Down Expand Up @@ -229,6 +231,11 @@ static void clean_child_exit_ex(int code, int from_signal)
if (pchild) {
if (!code && !from_signal) {
ap_run_child_stopping(pchild, !retained->mpm->is_ungraceful);
if (!retained->mpm->is_ungraceful) {
while (apr_atomic_read32(&connection_count) > 0) {
apr_sleep(apr_time_from_msec(100));
}
}
ap_run_child_stopped(pchild, !retained->mpm->is_ungraceful);
}
apr_pool_destroy(pchild);
Expand Down Expand Up @@ -380,6 +387,16 @@ static void just_die(int sig)
/* volatile because it's updated from a signal handler */
static int volatile die_now = 0;

static void ap_mpm_note_extra_connection_added(void)
{
apr_atomic_inc32(&connection_count);
}

static void ap_mpm_note_extra_connection_removed(void)
{
apr_atomic_dec32(&connection_count);
}

static void stop_listening(int sig)
{
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
Expand Down Expand Up @@ -1321,6 +1338,9 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp
apr_status_t rv;
const char *userdata_key = "mpm_prefork_module";

APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_added);
APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_removed);

debug = ap_exists_config_define("DEBUG");

if (debug) {
Expand Down
18 changes: 18 additions & 0 deletions server/mpm/winnt/child.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,21 @@ static apr_thread_mutex_t *ctxpool_lock;
static winnt_conn_ctx_t *ctxpool_head = NULL;
static apr_uint32_t num_completion_contexts = 0;
static apr_uint32_t max_num_completion_contexts = 0;
static apr_uint32_t extra_connection_count = 0;
static HANDLE ThreadDispatchIOCP = NULL;
static HANDLE ctxpool_wait_event = NULL;

/* Connections a module accepted itself, which the worker threads do not serve. */
void ap_mpm_note_extra_connection_added(void)
{
apr_atomic_inc32(&extra_connection_count);
}

void ap_mpm_note_extra_connection_removed(void)
{
apr_atomic_dec32(&extra_connection_count);
}

static void mpm_recycle_completion_context(winnt_conn_ctx_t *context)
{
/* Recycle the completion context.
Expand Down Expand Up @@ -1237,6 +1249,12 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid)
}
}

/* Drain externally accepted connections within what is left of the deadline. */
while (apr_atomic_read32(&extra_connection_count) > 0 && time_remains >= 0) {
Sleep(100);
time_remains -= 100;
}

if (threads_created) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00363)
"Child: Waiting for %d threads timed out, terminating process.",
Expand Down
3 changes: 3 additions & 0 deletions server/mpm/winnt/mpm_winnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,9 @@ static int winnt_pre_config(apr_pool_t *pconf_, apr_pool_t *plog, apr_pool_t *pt
* -k runservice [WinNT errors logged from rewrite_args]
*/

APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_added);
APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_removed);

/* Initialize shared static objects.
* TODO: Put config related statics into an sconf structure.
*/
Expand Down
2 changes: 2 additions & 0 deletions server/mpm/winnt/mpm_winnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ void hold_console_open_on_error(void);

/* From child.c: */
void child_main(apr_pool_t *pconf, DWORD parent_pid);
void ap_mpm_note_extra_connection_added(void);
void ap_mpm_note_extra_connection_removed(void);

#endif /* APACHE_MPM_WINNT_H */
/** @} */
21 changes: 21 additions & 0 deletions server/mpm/worker/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "apr_thread_mutex.h"
#include "apr_proc_mutex.h"
#include "apr_poll.h"
#include "apr_atomic.h"

#include <stdlib.h>

Expand Down Expand Up @@ -117,6 +118,7 @@
* Actual definitions of config globals
*/

static apr_uint32_t connection_count = 0; /* Number of open connections */
static int threads_per_child = 0; /* Worker threads per child */
static int ap_daemons_to_start = 0;
static int min_spare_threads = 0;
Expand Down Expand Up @@ -511,6 +513,16 @@ static void check_infinite_requests(void)
}
}

static void ap_mpm_note_extra_connection_added(void)
{
apr_atomic_inc32(&connection_count);
}

static void ap_mpm_note_extra_connection_removed(void)
{
apr_atomic_dec32(&connection_count);
}

static void unblock_signal(int sig)
{
sigset_t sig_mask;
Expand Down Expand Up @@ -1328,6 +1340,12 @@ static void child_main(int child_num_arg, int child_bucket)
rv == AP_MPM_PODX_GRACEFUL ? ST_GRACEFUL : ST_UNGRACEFUL);
}

if (terminate_mode == ST_GRACEFUL) {
while (apr_atomic_read32(&connection_count) > 0) {
apr_sleep(apr_time_from_msec(100));
}
}

free(threads);

clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
Expand Down Expand Up @@ -2103,6 +2121,9 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_status_t rv;
const char *userdata_key = "mpm_worker_module";

APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_added);
APR_REGISTER_OPTIONAL_FN(ap_mpm_note_extra_connection_removed);

debug = ap_exists_config_define("DEBUG");

if (debug) {
Expand Down