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) {