[prev in list] [next in list] [prev in thread] [next in thread]
List: apache-cvs
Subject: svn commit: r451279 - /httpd/httpd/trunk/server/eor_bucket.c
From: rpluem () apache ! org
Date: 2006-09-29 13:15:09
Message-ID: 20060929131509.A3EE31A984D () eris ! apache ! org
[Download RAW message or body]
Author: rpluem
Date: Fri Sep 29 06:15:08 2006
New Revision: 451279
URL: http://svn.apache.org/viewvc?view=rev&rev=451279
Log:
* Move the tasks of eor_bucket_destroy (status update, transaction logging) to
a cleanup function that is registered with the request pool.
eor_bucket_destroy only destroys the request pool if there is still a request
at this point of time which triggers the call of the cleanup function.
This is needed as the eor bucket could be (and usually is) allocated from
a pool different from the request pool (the connection pool in this case).
This can lead to situations where eor_bucket_destroy is called at a point of
time when the request pool had been already destroyed. But the status update
and the transaction logging rely on the request pool.
In practise this happens with the worker MPM if the client refuses to read
the response from the handler. Then the unsent data (including the
eor bucket) remains in a brigade allocated from the connection pool which
is the parent of the request pool. This brigade is cleaned up during the
cleanup of the ptrans pool in worker_thread. As the request pool gets
destroyed during this cleanup operation *before* the brigade gets cleaned up
eor_bucket_destroy starts the status update and the transaction logging with
a destroyed request pool which leads to a segfault.
Modified:
httpd/httpd/trunk/server/eor_bucket.c
Modified: httpd/httpd/trunk/server/eor_bucket.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/eor_bucket.c?view=diff&rev=451279&r1=451278&r2=451279
==============================================================================
--- httpd/httpd/trunk/server/eor_bucket.c (original)
+++ httpd/httpd/trunk/server/eor_bucket.c Fri Sep 29 06:15:08 2006
@@ -19,6 +19,27 @@
#include "http_protocol.h"
#include "scoreboard.h"
+static apr_status_t eor_bucket_cleanup(void *data)
+{
+ apr_bucket *b = (apr_bucket *)data;
+ request_rec *r = (request_rec *)b->data;
+
+ if (r != NULL) {
+ /*
+ * If eor_bucket_destroy is called after us, this prevents
+ * eor_bucket_destroy from trying to destroy the pool again.
+ */
+ b->data = NULL;
+ /* Update child status and log the transaction */
+ ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
+ ap_run_log_transaction(r);
+ if (ap_extended_status) {
+ ap_increment_counts(r->connection->sbh, r);
+ }
+ }
+ return APR_SUCCESS;
+}
+
static apr_status_t eor_bucket_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
{
@@ -45,18 +66,26 @@
APR_BUCKET_INIT(b);
b->free = apr_bucket_free;
b->list = list;
+ if (r) {
+ /*
+ * Register a cleanup for the request pool as the eor bucket could
+ * have been allocated from a different pool then the request pool
+ * e.g. the parent pool of the request pool. In this case
+ * eor_bucket_destroy might be called at a point of time when the
+ * request pool had been already destroyed.
+ */
+ apr_pool_cleanup_register(r->pool, (void *)b, eor_bucket_cleanup,
+ apr_pool_cleanup_null);
+ }
return ap_bucket_eor_make(b, r);
}
static void eor_bucket_destroy(void *data)
{
request_rec *r = (request_rec *)data;
- if (r != NULL) {
- ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
- ap_run_log_transaction(r);
- if (ap_extended_status) {
- ap_increment_counts(r->connection->sbh, r);
- }
+
+ if (r) {
+ /* eor_bucket_cleanup will be called when the pool gets destroyed */
apr_pool_destroy(r->pool);
}
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic