]> granicus.if.org Git - libnl/commitdiff
cache: Add reference counter to caches
authorThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 19:45:44 +0000 (20:45 +0100)
committerThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 19:45:44 +0000 (20:45 +0100)
Signed-off-by: Thomas Graf <tgraf@suug.ch>
include/netlink-types.h
include/netlink/cache.h
lib/cache.c

index 02ecf0488a0b36f98692e90f64cc32946666219e..2bb4f0a26f37782fe6e3160a47e42b507ef7ab30 100644 (file)
@@ -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;
index 1eb14274ec333ff572c24c104f7ba828dd43dad2..0bd4037454cbbab8d671c4856947d90eb272fad4 100644 (file)
@@ -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 */
index b776abfcfe2d57194c8db80d2a452feb3128c70c..257a41b39d6e9d1ccbedb91aa63dc086f174261c 100644 (file)
@@ -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);
 }
 
 /** @} */