Bug 4989: Leaking StoreEntry objects on Cache Digest rebuilds (#487)
When writing a newly generated Cache Digest to cache, Squid relied on a
cache key collision to purge the old digest entry. Since
4310f8b, the
collision resolution method -- forcePublicKey() -- leaked an idle (i.e.
lock_count=0) digest entry. If Squid still had unlocked entries lying
around, then the problem could extend to clashes unrelated to Digests.
Until
4310f8b, StoreEntry::forcePublicKey() called setPrivateKey()
before releasing the old entry. That explicit call was wasteful in many
cases, but, unbeknownst to its removal authors, it allowed release() to
destroy an idle Cache Digest entry by effectively disabling the
ENTRY_SPECIAL hack in StoreEntry::locked().
This change removes the ENTRY_SPECIAL hack in StoreEntry::locked(),
addressing an old TODO. The two ENTRY_SPECIAL creators (icons and Cache
Digests) now lock their entries to prevent their unwanted destruction.
Also explicitly release the old Cache Digest entry (instead of relying
on the implicit key collision) to avoid the unchecked assumption that
the Cache Digest key never changes.