From 02a0e3b89d2ea1b984365e692c910668d75c6dcd Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Tue, 27 Dec 2011 19:42:28 +0100 Subject: Upstream tarball 2.2.11 --- server/config.c | 1 + server/main.c | 10 ++++++ server/mpm/experimental/event/event.c | 4 +-- server/mpm/worker/fdqueue.c | 12 +++++-- server/util.c | 68 +++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) (limited to 'server') diff --git a/server/config.c b/server/config.c index d10f4afe..9747c284 100644 --- a/server/config.c +++ b/server/config.c @@ -378,6 +378,7 @@ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r) "handler \"%s\" not found for: %s", r->handler, r->filename); } if ((result != OK) && (result != DONE) && (result != DECLINED) + && (result != AP_FILTER_ERROR) && !ap_is_HTTP_VALID_RESPONSE(result)) { /* If a module is deliberately returning something else * (request_rec in non-HTTP or proprietary extension?) diff --git a/server/main.c b/server/main.c index 22c0b683..24a54d3f 100644 --- a/server/main.c +++ b/server/main.c @@ -254,9 +254,19 @@ static void show_compile_settings(void) #endif } +#define TASK_SWITCH_SLEEP 10000 + static void destroy_and_exit_process(process_rec *process, int process_exit_value) { + /* + * Sleep for TASK_SWITCH_SLEEP micro seconds to cause a task switch on + * OS layer and thus give possibly started piped loggers a chance to + * process their input. Otherwise it is possible that they get killed + * by us before they can do so. In this case maybe valueable log messages + * might get lost. + */ + apr_sleep(TASK_SWITCH_SLEEP); apr_pool_destroy(process->pool); /* and destroy all descendent pools */ apr_terminate(); exit(process_exit_value); diff --git a/server/mpm/experimental/event/event.c b/server/mpm/experimental/event/event.c index 261468ea..bbee899e 100644 --- a/server/mpm/experimental/event/event.c +++ b/server/mpm/experimental/event/event.c @@ -650,7 +650,7 @@ static int process_socket(apr_pool_t * p, apr_socket_t * sock, ap_lingering_close(c); apr_pool_clear(p); ap_push_pool(worker_queue_info, p); - return 1; + return 0; } else if (cs->state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) { apr_status_t rc; @@ -680,7 +680,7 @@ static int process_socket(apr_pool_t * p, apr_socket_t * sock, AP_DEBUG_ASSERT(rc == APR_SUCCESS); } } - return 0; + return 1; } /* requests_this_child has gone to zero or below. See if the admin coded diff --git a/server/mpm/worker/fdqueue.c b/server/mpm/worker/fdqueue.c index d46dd536..dfbe8c47 100644 --- a/server/mpm/worker/fdqueue.c +++ b/server/mpm/worker/fdqueue.c @@ -155,7 +155,15 @@ apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, * region, one of two things may have happened: * - If the idle worker count is still zero, the * workers are all still busy, so it's safe to - * block on a condition variable. + * block on a condition variable, BUT + * we need to check for idle worker count again + * when we are signaled since it can happen that + * we are signaled by a worker thread that went idle + * but received a context switch before it could + * tell us. If it does signal us later once it is on + * CPU again there might be no idle worker left. + * See + * https://issues.apache.org/bugzilla/show_bug.cgi?id=45605#c4 * - If the idle worker count is nonzero, then a * worker has become idle since the first check * of queue_info->idlers above. It's possible @@ -166,7 +174,7 @@ apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t *queue_info, * now nonzero, it's safe for this function to * return immediately. */ - if (queue_info->idlers == 0) { + while (queue_info->idlers == 0) { rv = apr_thread_cond_wait(queue_info->wait_for_idler, queue_info->idlers_mutex); if (rv != APR_SUCCESS) { diff --git a/server/util.c b/server/util.c index e1be3d18..3c927c23 100644 --- a/server/util.c +++ b/server/util.c @@ -2146,3 +2146,71 @@ AP_DECLARE(char *) ap_append_pid(apr_pool_t *p, const char *string, delim, getpid()); } + +/** + * Parse a given timeout parameter string into an apr_interval_time_t value. + * The unit of the time interval is given as postfix string to the numeric + * string. Currently the following units are understood: + * + * ms : milliseconds + * s : seconds + * mi[n] : minutes + * h : hours + * + * If no unit is contained in the given timeout parameter the default_time_unit + * will be used instead. + * @param timeout_parameter The string containing the timeout parameter. + * @param timeout The timeout value to be returned. + * @param default_time_unit The default time unit to use if none is specified + * in timeout_parameter. + * @return Status value indicating whether the parsing was successful or not. + */ +AP_DECLARE(apr_status_t) ap_timeout_parameter_parse( + const char *timeout_parameter, + apr_interval_time_t *timeout, + const char *default_time_unit) +{ + char *endp; + const char *time_str; + apr_int64_t tout; + + tout = apr_strtoi64(timeout_parameter, &endp, 10); + if (errno) { + return errno; + } + if (!endp || !*endp) { + time_str = default_time_unit; + } + else { + time_str = endp; + } + + switch (*time_str) { + /* Time is in seconds */ + case 's': + *timeout = (apr_interval_time_t) apr_time_from_sec(tout); + break; + case 'h': + /* Time is in hours */ + *timeout = (apr_interval_time_t) apr_time_from_sec(tout * 3600); + break; + case 'm': + switch (*(++time_str)) { + /* Time is in miliseconds */ + case 's': + *timeout = (apr_interval_time_t) tout * 1000; + break; + /* Time is in minutes */ + case 'i': + *timeout = (apr_interval_time_t) apr_time_from_sec(tout * 60); + break; + default: + return APR_EGENERAL; + } + break; + default: + return APR_EGENERAL; + } + return APR_SUCCESS; +} + -- cgit v1.2.3