summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2012-11-15 20:45:44 +0100
committerThomas Graf <tgraf@suug.ch>2012-11-15 20:45:44 +0100
commitc658a6eef8bfaa9347305e532f063cb848087d31 (patch)
tree491291eba0f494c91bf3393258b2cb68f1f6892f
parentcb25338ac35b5174f03c19e00733d9366f6b9482 (diff)
downloadlibnl-c658a6eef8bfaa9347305e532f063cb848087d31.tar.gz
cache: Add reference counter to caches
Signed-off-by: Thomas Graf <tgraf@suug.ch>
-rw-r--r--include/netlink-types.h1
-rw-r--r--include/netlink/cache.h1
-rw-r--r--lib/cache.c34
3 files changed, 29 insertions, 7 deletions
diff --git a/include/netlink-types.h b/include/netlink-types.h
index 02ecf04..2bb4f0a 100644
--- a/include/netlink-types.h
+++ b/include/netlink-types.h
@@ -79,6 +79,7 @@ struct nl_cache
int c_nitems;
int c_iarg1;
int c_iarg2;
+ int c_refcnt;
unsigned int c_flags;
struct nl_hash_table * hashtable;
struct nl_cache_ops * c_ops;
diff --git a/include/netlink/cache.h b/include/netlink/cache.h
index 1eb1427..0bd4037 100644
--- a/include/netlink/cache.h
+++ b/include/netlink/cache.h
@@ -50,6 +50,7 @@ extern struct nl_cache * nl_cache_subset(struct nl_cache *,
struct nl_object *);
extern struct nl_cache * nl_cache_clone(struct nl_cache *);
extern void nl_cache_clear(struct nl_cache *);
+extern void nl_cache_get(struct nl_cache *);
extern void nl_cache_free(struct nl_cache *);
/* Cache modification */
diff --git a/lib/cache.c b/lib/cache.c
index b776abf..257a41b 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
@@ -191,6 +191,7 @@ struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops)
nl_init_list_head(&cache->c_items);
cache->c_ops = ops;
cache->c_flags |= ops->co_flags;
+ cache->c_refcnt = 1;
/*
* If object type provides a hash keygen
@@ -365,6 +366,26 @@ void nl_cache_clear(struct nl_cache *cache)
nl_cache_remove(obj);
}
+static void __nl_cache_free(struct nl_cache *cache)
+{
+ nl_cache_clear(cache);
+
+ if (cache->hashtable)
+ nl_hash_table_free(cache->hashtable);
+
+ NL_DBG(1, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache));
+ free(cache);
+}
+
+/**
+ * Increase reference counter of cache
+ * @arg cache Cache
+ */
+void nl_cache_get(struct nl_cache *cache)
+{
+ cache->c_refcnt++;
+}
+
/**
* Free a cache.
* @arg cache Cache to free.
@@ -379,13 +400,12 @@ void nl_cache_free(struct nl_cache *cache)
if (!cache)
return;
- nl_cache_clear(cache);
+ cache->c_refcnt--;
+ NL_DBG(4, "Returned cache reference %p, %d remaining\n",
+ cache, cache->c_refcnt);
- if (cache->hashtable)
- nl_hash_table_free(cache->hashtable);
-
- NL_DBG(1, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache));
- free(cache);
+ if (cache->c_refcnt <= 0)
+ __nl_cache_free(cache);
}
/** @} */