diff options
author | Alexander Larsson <alexl@redhat.com> | 2018-05-23 15:08:12 +0200 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2018-05-25 14:42:05 +0900 |
commit | a63b9c622e240ec0d8f9d83d286db1b55849f374 (patch) | |
tree | 79c4e4d4b0288248c455431e38e3eb8b6960b480 /src/fccache.c | |
parent | 94080c3d48686117b83acddf516258647b571f03 (diff) |
Add FcCacheAllocate() helper
This lets you allocate a chunk of memory that will be freed when the cache
is freed.
https://bugs.freedesktop.org/show_bug.cgi?id=106618
Diffstat (limited to 'src/fccache.c')
-rw-r--r-- | src/fccache.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/fccache.c b/src/fccache.c index 27b1282..041c77b 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -443,6 +443,7 @@ struct _FcCacheSkip { FcCache *cache; FcRef ref; intptr_t size; + void *allocated; dev_t cache_dev; ino_t cache_ino; time_t cache_mtime; @@ -568,6 +569,7 @@ FcCacheInsert (FcCache *cache, struct stat *cache_stat) s->cache = cache; s->size = cache->size; + s->allocated = NULL; FcRefInit (&s->ref, 1); if (cache_stat) { @@ -642,6 +644,7 @@ FcCacheRemoveUnlocked (FcCache *cache) FcCacheSkip **update[FC_CACHE_MAX_LEVEL]; FcCacheSkip *s, **next; int i; + void *allocated; /* * Find links along each chain @@ -659,6 +662,15 @@ FcCacheRemoveUnlocked (FcCache *cache) *update[i] = s->next[i]; while (fcCacheMaxLevel > 0 && fcCacheChains[fcCacheMaxLevel - 1] == NULL) fcCacheMaxLevel--; + + allocated = s->allocated; + while (allocated) + { + /* First element in allocated chunk is the free list */ + next = *(void **)allocated; + free (allocated); + allocated = next; + } free (s); } @@ -728,6 +740,30 @@ FcCacheObjectDereference (void *object) unlock_cache (); } +void * +FcCacheAllocate (FcCache *cache, size_t len) +{ + FcCacheSkip *skip; + void *allocated = NULL; + + lock_cache (); + skip = FcCacheFindByAddrUnlocked (cache); + if (skip) + { + void *chunk = malloc (sizeof (void *) + len); + if (chunk) + { + /* First element in allocated chunk is the free list */ + *(void **)chunk = skip->allocated; + skip->allocated = chunk; + /* Return the rest */ + allocated = ((FcChar8 *)chunk) + sizeof (void *); + } + } + unlock_cache (); + return allocated; +} + void FcCacheFini (void) { |