This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch span-gl-clean
in repository efl.
View the commit online.
commit 76aab801737e9792e3c2245ef42052793c8d7006
Author: [email protected] <[email protected]>
AuthorDate: Sun Sep 13 18:09:38 2026 -0600
evas: walk the generic cache LRU with EINA_LIST_REVERSE_FOREACH_SAFE
Raster's review pointed out that _generic_cache_trim() walks its LRU
list by hand, with eina_list_last(), eina_list_prev() and
eina_list_data_get(), where EFL has a macro for exactly this.
Use EINA_LIST_REVERSE_FOREACH_SAFE. The loop removes and frees the
current node, so it needs the SAFE variant, which saves the previous
node before running the body. EINA_LIST_FREE does not fit: the trim has
to start from the tail, skip entries that are still handed out, stop
once the cache is back under budget, and never remove the head.
Also drop a copy of the "Never evict the entry just inserted" comment
that appeared twice in a row.
Behaviour is unchanged. A standalone test against libevas with a 1 KB
budget checked that entries are evicted oldest first, that handed-out
entries and the newest entry survive, that an entry bigger than the
budget is kept, and that the 50-entry cap still applies without a size
function. It passed, and valgrind found no errors. ector_suite and
evas_suite pass.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
src/lib/evas/common/evas_common_generic_cache.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/lib/evas/common/evas_common_generic_cache.c b/src/lib/evas/common/evas_common_generic_cache.c
index 428b9eba2c..649084c3a7 100644
--- a/src/lib/evas/common/evas_common_generic_cache.c
+++ b/src/lib/evas/common/evas_common_generic_cache.c
@@ -30,15 +30,14 @@ _generic_cache_budget(void)
static void
_generic_cache_trim(Generic_Cache *cache)
{
+ Generic_Cache_Entry *entry;
Eina_List *l, *prev;
int count = (int)eina_list_count(cache->lru_list);
if (!cache->size_func && (count <= 50)) return;
- for (l = eina_list_last(cache->lru_list); l; l = prev)
+ EINA_LIST_REVERSE_FOREACH_SAFE(cache->lru_list, l, prev, entry)
{
- Generic_Cache_Entry *entry = eina_list_data_get(l);
-
if (cache->size_func)
{
if ((cache->bytes <= cache->budget) &&
@@ -46,12 +45,6 @@ _generic_cache_trim(Generic_Cache *cache)
}
else if (count <= 50) break;
- // Never evict the entry just inserted. It is at the head, and when
- // the budget is smaller than a single surface the head is also the
- // tail - trimming it would free the very data the caller stored a
- // moment ago and is about to draw with. A budget is advisory when
- // one item does not fit; a use-after-free is not.
-
// Never evict the entry just inserted. It is at the head, and when
// the budget is smaller than a single surface the head is also the
// tail - trimming it would free the very data the caller stored a
@@ -59,7 +52,6 @@ _generic_cache_trim(Generic_Cache *cache)
// one item does not fit; a use-after-free is not.
if (l == cache->lru_list) break;
- prev = eina_list_prev(l);
if (!entry || (entry->ref > 1)) continue;
eina_hash_del(cache->hash, &entry->key, entry);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.