]> granicus.if.org Git - libnl/commitdiff
cache: Add reference counter to cache operations
authorThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 22:48:03 +0000 (23:48 +0100)
committerThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 23:17:50 +0000 (00:17 +0100)
Signed-off-by: Thomas Graf <tgraf@suug.ch>
include/netlink/cache-api.h
lib/cache_mngt.c

index dd426717da296576e65158b7c48e118239637152..f2111b95eb5331861002fbe4a97fc882b4d4b679 100644 (file)
@@ -192,6 +192,9 @@ struct nl_cache_ops
        /** cache flags */
        unsigned int            co_flags;
 
+       /** Reference counter */
+       unsigned int            co_refcnt;
+
        /** Group definition */
        struct nl_af_group *    co_groups;
        
@@ -262,6 +265,9 @@ struct nl_cache_ops
        struct nl_msgtype       co_msgtypes[];
 };
 
+extern void    nl_cache_ops_get(struct nl_cache_ops *);
+extern void    nl_cache_ops_put(struct nl_cache_ops *);
+
 /** @} */
 
 #ifdef __cplusplus
index 65c47070ec530ddd6bc253a7df7289038cbf2a41..d0dfcdda63347bf9b58b4e11684b2879cd6df243 100644 (file)
@@ -49,6 +49,24 @@ struct nl_cache_ops *__nl_cache_ops_lookup(const char *name)
        return NULL;
 }
 
+/**
+ * Increment reference counter
+ * @arg ops            Cache operations
+ */
+void nl_cache_ops_get(struct nl_cache_ops *ops)
+{
+       ops->co_refcnt++;
+}
+
+/**
+ * Decrement reference counter
+ * @arg ops            Cache operations
+ */
+void nl_cache_ops_put(struct nl_cache_ops *ops)
+{
+       ops->co_refcnt--;
+}
+
 /**
  * Lookup the set cache operations of a certain cache type
  * @arg name           name of the cache type
@@ -182,6 +200,7 @@ int nl_cache_mngt_register(struct nl_cache_ops *ops)
                return -NLE_EXIST;
        }
 
+       ops->co_refcnt = 0;
        ops->co_next = cache_ops;
        cache_ops = ops;
        nl_write_unlock(&cache_ops_lock);
@@ -205,24 +224,31 @@ int nl_cache_mngt_register(struct nl_cache_ops *ops)
 int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
 {
        struct nl_cache_ops *t, **tp;
+       int err = 0;
 
        nl_write_lock(&cache_ops_lock);
 
+       if (ops->co_refcnt > 0) {
+               err = -NLE_BUSY;
+               goto errout;
+       }
+
        for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next)
                if (t == ops)
                        break;
 
        if (!t) {
-               nl_write_unlock(&cache_ops_lock);
-               return -NLE_NOCACHE;
+               err = -NLE_NOCACHE;
+               goto errout;
        }
 
        NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name);
 
        *tp = t->co_next;
+errout:
        nl_write_unlock(&cache_ops_lock);
 
-       return 0;
+       return err;
 }
 
 /** @} */