From f3533551c3a7e3a08239fee25f55de7cdcb81d70 Mon Sep 17 00:00:00 2001 From: Arndt Kaiser <42686074+madmajestro@users.noreply.github.com> Date: Fri, 7 Mar 2025 19:06:54 +0100 Subject: [PATCH] Cleanup of entries should not be skipped when using default settings By default (apc.smart = 0), apc_cache_default_expunge() should not skip cleanup of old entries. This may cause insertion of new entries to fail unnecessarily, which is unexpected behavior. --- apc_cache.c | 52 +++++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/apc_cache.c b/apc_cache.c index 3544c097..9652a03d 100644 --- a/apc_cache.c +++ b/apc_cache.c @@ -735,8 +735,7 @@ PHP_APCU_API void apc_cache_clear(apc_cache_t* cache) PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size) { time_t t; - size_t suitable = 0L; - size_t available = 0L; + size_t i; if (!cache) { return; @@ -751,43 +750,38 @@ PHP_APCU_API void apc_cache_default_expunge(apc_cache_t* cache, size_t size) return; } - /* make suitable selection */ - suitable = (cache->smart > 0L) ? (size_t) (cache->smart * size) : (size_t) (cache->sma->size/2); - /* gc */ apc_cache_wlocked_gc(cache); - /* get available */ - available = apc_sma_get_avail_mem(cache->sma); - /* check that expunge is necessary */ - if (available < suitable) { - size_t i; - - /* look for junk */ - for (i = 0; i < cache->nslots; i++) { - apc_cache_entry_t **entry = &cache->slots[i]; - while (*entry) { - if (apc_cache_entry_expired(cache, *entry, t)) { - apc_cache_wlocked_remove_entry(cache, entry); - continue; - } + if (cache->smart > 0L && apc_sma_get_avail_mem(cache->sma) >= (size_t) (cache->smart * size)) { + apc_cache_wunlock(cache); + return; + } - /* grab next entry */ - entry = &(*entry)->next; + /* look for junk */ + for (i = 0; i < cache->nslots; i++) { + apc_cache_entry_t **entry = &cache->slots[i]; + while (*entry) { + if (apc_cache_entry_expired(cache, *entry, t)) { + apc_cache_wlocked_remove_entry(cache, entry); + continue; } - } - /* if the cache now has space, then reset last key */ - if (apc_sma_get_avail_size(cache->sma, size)) { - /* wipe lastkey */ - memset(&cache->header->lastkey, 0, sizeof(apc_cache_slam_key_t)); - } else { - /* with not enough space left in cache, we are forced to expunge */ - apc_cache_wlocked_real_expunge(cache); + /* grab next entry */ + entry = &(*entry)->next; } } + /* if the cache now has space, then reset last key */ + if (apc_sma_get_avail_size(cache->sma, size)) { + /* wipe lastkey */ + memset(&cache->header->lastkey, 0, sizeof(apc_cache_slam_key_t)); + } else { + /* with not enough space left in cache, we are forced to expunge */ + apc_cache_wlocked_real_expunge(cache); + } + apc_cache_wunlock(cache); } /* }}} */