summaryrefslogtreecommitdiff
path: root/cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'cache.c')
-rw-r--r--cache.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/cache.c b/cache.c
index ea3115a..18dc8b7 100644
--- a/cache.c
+++ b/cache.c
@@ -45,6 +45,12 @@ cache_t* cache_create(const char *name, size_t bufsize, size_t align,
return ret;
}
+void cache_set_limit(cache_t *cache, int limit) {
+ pthread_mutex_lock(&cache->mutex);
+ cache->limit = limit;
+ pthread_mutex_unlock(&cache->mutex);
+}
+
static inline void* get_object(void *ptr) {
#ifndef NDEBUG
uint64_t *pre = ptr;
@@ -82,7 +88,7 @@ void* do_cache_alloc(cache_t *cache) {
if (cache->freecurr > 0) {
ret = cache->ptr[--cache->freecurr];
object = get_object(ret);
- } else {
+ } else if (cache->limit == 0 || cache->total < cache->limit) {
object = ret = malloc(cache->bufsize);
if (ret != NULL) {
object = get_object(ret);
@@ -94,6 +100,8 @@ void* do_cache_alloc(cache_t *cache) {
}
cache->total++;
}
+ } else {
+ object = NULL;
}
#ifndef NDEBUG
@@ -134,7 +142,14 @@ void do_cache_free(cache_t *cache, void *ptr) {
}
ptr = pre;
#endif
- if (cache->freecurr < cache->freetotal) {
+ if (cache->limit > cache->total) {
+ /* Allow freeing in case the limit was revised downward */
+ if (cache->destructor) {
+ cache->destructor(ptr, NULL);
+ }
+ free(ptr);
+ cache->total--;
+ } else if (cache->freecurr < cache->freetotal) {
cache->ptr[cache->freecurr++] = ptr;
} else {
/* try to enlarge free connections array */