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_proxy_beacon: Back-end reverse proxy servers can announce
themselves and be auto-added to their front-end proxy balancer.
[Jim Jagielski]
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
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