dgaudet 98/05/06 12:49:52
Modified: src/ap ap_snprintf.c src/include ap.h src/main alloc.c Log: add various comments based on comments from Martin to me Revision Changes Path 1.20 +3 -0 apache-1.3/src/ap/ap_snprintf.c Index: ap_snprintf.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/ap/ap_snprintf.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- ap_snprintf.c 1998/04/19 19:19:36 1.19 +++ ap_snprintf.c 1998/05/06 19:49:46 1.20 @@ -966,6 +966,9 @@ static int snprintf_flush(ap_vformatter_buff *vbuff) { + /* if the buffer fills we have to abort immediately, there is no way + * to "flush" an ap_snprintf... there's nowhere to flush it to. + */ return -1; } 1.14 +11 -0 apache-1.3/src/include/ap.h Index: ap.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/ap.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- ap.h 1998/05/03 17:31:06 1.13 +++ ap.h 1998/05/06 19:49:48 1.14 @@ -121,6 +121,17 @@ * example, it's possible when the output exactly matches the buffer * space available that curpos == endpos will be true when * ap_vformatter returns. + * + * ap_vformatter does not call out to any other code, it is entirely + * self-contained. This allows the callers to do things which are + * otherwise "unsafe". For example, ap_psprintf uses the "scratch" + * space at the unallocated end of a block, and doesn't actually + * complete the allocation until ap_vformatter returns. ap_psprintf + * would be completely broken if ap_vformatter were to call anything + * that used a pool. Similarly http_bprintf() uses the "scratch" + * space at the end of its output buffer, and doesn't actually note + * that the space is in use until it either has to flush the buffer + * or until ap_vformatter returns. */ typedef struct { 1.91 +12 -1 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.90 retrieving revision 1.91 diff -u -r1.90 -r1.91 --- alloc.c 1998/05/06 06:26:17 1.90 +++ alloc.c 1998/05/06 19:49:50 1.91 @@ -783,11 +783,17 @@ return res; } -/* psprintf is implemented by writing directly into the current +/* ap_psprintf is implemented by writing directly into the current * block of the pool, starting right at first_avail. If there's * insufficient room, then a new block is allocated and the earlier * output is copied over. The new block isn't linked into the pool * until all the output is done. + * + * Note that this is completely safe because nothing else can + * allocate in this pool while ap_psprintf is running. alarms are + * blocked, and the only thing outside of alloc.c that's invoked + * is ap_vformatter -- which was purposefully written to be + * self-contained with no callouts. */ struct psprintf_data { @@ -833,6 +839,7 @@ (void) ap_release_mutex(alloc_mutex); memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len); ps->vbuff.curpos = nblok->h.first_avail + cur_len; + /* save a byte for the NUL terminator */ ps->vbuff.endpos = nblok->h.endp - 1; /* did we allocate the current blok? if so free it up */ @@ -845,6 +852,10 @@ } ps->blok = nblok; ps->got_a_new_block = 1; + /* note that we've deliberately not linked the new block onto + * the pool yet... because we may need to flush again later, and + * we'd have to spend more effort trying to unlink the block. + */ return 0; #endif }