=== modified file 'src/HttpHeader.cc' --- src/HttpHeader.cc 2011-05-02 01:14:30 +0000 +++ src/HttpHeader.cc 2011-05-20 21:09:56 +0000 @@ -368,109 +368,111 @@ assert(label); memset(hs, 0, sizeof(HttpHeaderStat)); hs->label = label; statHistEnumInit(&hs->hdrUCountDistr, 32); /* not a real enum */ statHistEnumInit(&hs->fieldTypeDistr, HDR_ENUM_END); statHistEnumInit(&hs->ccTypeDistr, CC_ENUM_END); statHistEnumInit(&hs->scTypeDistr, SC_ENUM_END); } /* * HttpHeader Implementation */ HttpHeader::HttpHeader() : owner (hoNone), len (0) { httpHeaderMaskInit(&mask, 0); } HttpHeader::HttpHeader(const http_hdr_owner_type anOwner): owner(anOwner), len(0) { - assert(anOwner > hoNone && anOwner <= hoReply); + assert(anOwner > hoNone && anOwner < hoEnd); debugs(55, 7, "init-ing hdr: " << this << " owner: " << owner); httpHeaderMaskInit(&mask, 0); } HttpHeader::HttpHeader(const HttpHeader &other): owner(other.owner), len(other.len) { httpHeaderMaskInit(&mask, 0); update(&other, NULL); // will update the mask as well } HttpHeader::~HttpHeader() { clean(); } HttpHeader & HttpHeader::operator =(const HttpHeader &other) { if (this != &other) { // we do not really care, but the caller probably does assert(owner == other.owner); clean(); update(&other, NULL); // will update the mask as well len = other.len; } return *this; } void HttpHeader::clean() { HttpHeaderPos pos = HttpHeaderInitPos; HttpHeaderEntry *e; - assert(owner > hoNone && owner <= hoReply); + assert(owner > hoNone && owner < hoEnd); debugs(55, 7, "cleaning hdr: " << this << " owner: " << owner); PROF_start(HttpHeaderClean); /* * An unfortunate bug. The entries array is initialized * such that count is set to zero. httpHeaderClean() seems to * be called both when 'hdr' is created, and destroyed. Thus, * we accumulate a large number of zero counts for 'hdr' before * it is ever used. Can't think of a good way to fix it, except * adding a state variable that indicates whether or not 'hdr' * has been used. As a hack, just never count zero-sized header * arrays. */ + if (owner <= hoReply) { if (0 != entries.count) statHistCount(&HttpHeaderStats[owner].hdrUCountDistr, entries.count); HttpHeaderStats[owner].destroyedCount++; HttpHeaderStats[owner].busyDestroyedCount += entries.count > 0; while ((e = getEntry(&pos))) { /* tmp hack to try to avoid coredumps */ if (e->id < 0 || e->id >= HDR_ENUM_END) { debugs(55, 0, "HttpHeader::clean BUG: entry[" << pos << "] is invalid (" << e->id << "). Ignored."); } else { statHistCount(&HttpHeaderStats[owner].fieldTypeDistr, e->id); /* yes, this deletion leaves us in an inconsistent state */ delete e; } } + } // if (owner <= hoReply) entries.clean(); httpHeaderMaskInit(&mask, 0); len = 0; PROF_stop(HttpHeaderClean); } /* append entries (also see httpHeaderUpdate) */ void HttpHeader::append(const HttpHeader * src) { const HttpHeaderEntry *e; HttpHeaderPos pos = HttpHeaderInitPos; assert(src); assert(src != this); debugs(55, 7, "appending hdr: " << this << " += " << src); while ((e = src->getEntry(&pos))) { addEntry(e->clone()); } }