summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorStefan Fritsch <sf@sfritsch.de>2011-12-27 19:42:28 +0100
committerStefan Fritsch <sf@sfritsch.de>2011-12-27 19:42:28 +0100
commit02a0e3b89d2ea1b984365e692c910668d75c6dcd (patch)
treeb9ba1c635c12bace3b2afbe7f548a0aab67102f5 /server
parent0268977037115539ad65a26e858aa0df8d18cd13 (diff)
downloadapache2-02a0e3b89d2ea1b984365e692c910668d75c6dcd.tar.gz
Upstream tarball 2.2.11upstream/2.2.11
Diffstat (limited to 'server')
-rw-r--r--server/config.c1
-rw-r--r--server/main.c10
-rw-r--r--server/mpm/experimental/event/event.c4
-rw-r--r--server/mpm/worker/fdqueue.c12
-rw-r--r--server/util.c68
5 files changed, 91 insertions, 4 deletions
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;
+}
+