dgaudet 98/01/27 02:00:46
Modified: src/main alloc.c alloc.h
src/modules/standard mod_negotiation.c
Log:
Another iteration in getting POOL_DEBUG to work correctly. It turns out
there are many more subtle interactions caused by the mod_negotiation
"fast redirect". So I added an API "hint" function pool_join()... which
is normally a nop, but if POOL_DEBUG is defined this tells the debugging
code that the sub pool is guaranteed to exist as long as the parent
pool does.
Revision Changes Path
1.71 +31 -0 apache-1.3/src/main/alloc.c
Index: alloc.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/alloc.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- alloc.c 1998/01/27 02:37:51 1.70
+++ alloc.c 1998/01/27 10:00:38 1.71
@@ -361,6 +361,9 @@
#ifdef ALLOC_USE_MALLOC
void *allocation_list;
#endif
+#ifdef POOL_DEBUG
+ struct pool *joined;
+#endif
};
pool *permanent_pool;
@@ -576,6 +579,9 @@
if (a == NULL) {
return 1;
}
+ while (a->joined) {
+ a = a->joined;
+ }
while (b) {
if (a == b) {
return 1;
@@ -583,6 +589,31 @@
b = b->parent;
}
return 0;
+}
+
+/* All blocks belonging to sub will be changed to point to p
+ * instead. This is a guarantee by the caller that sub will not
+ * be destroyed before p is.
+ */
+API_EXPORT(void) pool_join(pool *p, pool *sub)
+{
+ union block_hdr *b;
+
+ if (!pool_is_ancestor(p, sub)) {
+ fprintf(stderr, "pool_join: p is not an ancestor of sub\n");
+ abort();
+ }
+ block_alarms();
+ while (p->joined) {
+ p = p->joined;
+ }
+ sub->joined = p;
+ for (b = global_block_list; b; b = b->h.global_next) {
+ if (b->h.owning_pool == sub) {
+ b->h.owning_pool = p;
+ }
+ }
+ unblock_alarms();
}
#endif
1.44 +9 -0 apache-1.3/src/main/alloc.h
Index: alloc.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/alloc.h,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- alloc.h 1998/01/26 19:50:10 1.43
+++ alloc.h 1998/01/27 10:00:40 1.44
@@ -87,6 +87,15 @@
API_EXPORT(pool *) make_sub_pool(pool *); /* All pools are subpools of
permanent_pool */
API_EXPORT(void) destroy_pool(pool *);
+/* used to guarantee to the pool debugging code that the sub pool will not be
+ * destroyed before the parent pool
+ */
+#ifndef POOL_DEBUG
+#define pool_join(a,b)
+#else
+API_EXPORT(void) pool_join(pool *p, pool *sub);
+#endif
+
/* Clearing out EVERYTHING in an pool... destroys any sub-pools */
API_EXPORT(void) clear_pool(struct pool *);
1.66 +11 -10 apache-1.3/src/modules/standard/mod_negotiation.c
Index: mod_negotiation.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_negotiation.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -r1.65 -r1.66
--- mod_negotiation.c 1998/01/26 19:50:22 1.65
+++ mod_negotiation.c 1998/01/27 10:00:44 1.66
@@ -2182,6 +2182,13 @@
set_neg_headers(r, neg, na_not_applied);
}
+ /* now do a "fast redirect" ... promote the sub_req into the main req */
+ /* We need to tell POOL_DEBUG that we're guaranteeing that sub_req->pool
+ * will exist as long as r->pool. Otherwise we run into troubles because
+ * some values in this request will be allocated in r->pool, and others
in
+ * sub_req->pool.
+ */
+ pool_join(r->pool, sub_req->pool);
r->filename = sub_req->filename;
r->handler = sub_req->handler;
r->content_type = sub_req->content_type;
@@ -2190,19 +2197,13 @@
r->content_language = sub_req->content_language;
r->finfo = sub_req->finfo;
r->per_dir_config = sub_req->per_dir_config;
- /* You may wonder why we're using the sub_req->pool here. It's to
support
- * POOL_DEBUG in alloc.c. sub_req->pool will have the same lifetime as
- * r->pool, we guarantee that by not destroying the sub request below.
- * We have to guarantee that because we've "promoted" some of the values
- * from sub_req->pool to r->foobar, like r->filename.
- */
/* copy output headers from subrequest, but leave negotiation headers */
- r->notes = overlay_tables(sub_req->pool, sub_req->notes, r->notes);
- r->headers_out = overlay_tables(sub_req->pool, sub_req->headers_out,
+ r->notes = overlay_tables(r->pool, sub_req->notes, r->notes);
+ r->headers_out = overlay_tables(r->pool, sub_req->headers_out,
r->headers_out);
- r->err_headers_out = overlay_tables(sub_req->pool,
sub_req->err_headers_out,
+ r->err_headers_out = overlay_tables(r->pool, sub_req->err_headers_out,
r->err_headers_out);
- r->subprocess_env = overlay_tables(sub_req->pool,
sub_req->subprocess_env,
+ r->subprocess_env = overlay_tables(r->pool, sub_req->subprocess_env,
r->subprocess_env);
avail_recs = (var_rec *) neg->avail_vars->elts;
for (j = 0; j < neg->avail_vars->nelts; ++j) {