[gs-commits] mupdf 1.16.1.82 Fix store behaviour when oversized.
[email protected] (Robin Watts) Fri, 4 Oct 2019 11:42:09 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 50c4c0176510ca068f13bbe04ad001ece9132523 Author: Robin Watts <[email protected]> Date: Thu Oct 3 17:57:45 2019 +0100 Fix store behaviour when oversized. The store can become oversized while objects that are in it are in use. The idea is that once they cease to be in used, the store should clear out enough to keep it below the specified maximum level. The current code fails to do this. When the store is oversized, if we drop a storable item and it ends up so that the only reference to it is from the store, we should bin it entirely so the store can shrink. Update fz_drop_storable to perform in this way. diff --git a/source/fitz/store.c b/source/fitz/store.c index f652b96..58c6e84 100644 --- a/source/fitz/store.c +++ b/source/fitz/store.c @@ -81,24 +81,6 @@ fz_keep_storable(fz_context *ctx, const fz_storable *sc) return fz_keep_imp(ctx, s, &s->refs); } -void -fz_drop_storable(fz_context *ctx, const fz_storable *sc) -{ - /* Explicitly drop const to allow us to use const - * sanely throughout the code. */ - fz_storable *s = (fz_storable *)sc; - - /* - If we are dropping the last reference to an object, then - it cannot possibly be in the store (as the store always - keeps a ref to everything in it, and doesn't drop via - this method. So we can simply drop the storable object - itself without any operations on the fz_store. - */ - if (fz_drop_imp(ctx, s, &s->refs)) - s->drop(ctx, s); -} - void *fz_keep_key_storable(fz_context *ctx, const fz_key_storable *sc) { return fz_keep_storable(ctx, &sc->storable); @@ -849,6 +831,47 @@ scavenge(fz_context *ctx, size_t tofree) return count != 0; } +void +fz_drop_storable(fz_context *ctx, const fz_storable *sc) +{ + /* Explicitly drop const to allow us to use const + * sanely throughout the code. */ + fz_storable *s = (fz_storable *)sc; + int num; + + if (s == NULL) + return; + + fz_lock(ctx, FZ_LOCK_ALLOC); + /* Drop the ref, and leave num as being the number of + * refs left (-1 meaning, "statically allocated"). */ + if (s->refs > 0) + { + (void)Memento_dropIntRef(s); + num = --s->refs; + } + else + num = -1; + + /* If we have just 1 ref left, it's possible that + * this ref is held by the store. If the store is + * oversized, we ought to throw any such references + * away to try to bring the store down to a "legal" + * size. Run a scavenge to check for this case. */ + if (num == 1 && ctx->store->size > ctx->store->max) + scavenge(ctx, ctx->store->size - ctx->store->max); + fz_unlock(ctx, FZ_LOCK_ALLOC); + + /* If we have no references to an object left, then + * it cannot possibly be in the store (as the store always + * keeps a ref to everything in it, and doesn't drop via + * this method). So we can simply drop the storable object + * itself without any operations on the fz_store. + */ + if (num == 0) + s->drop(ctx, s); +} + /* External function for callers to use to scavenge while trying allocations. http://git.ghostscript.com/?p=mupdf.git;a=commit;h=50c4c0176510ca068f13bbe04ad001ece9132523 -- MuPDF library Artifex Software, Inc.