From 1a2c3e36a8aa6b3a0a568f587669c7c8d5ddac28 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 15 Nov 2012 23:48:03 +0100 Subject: cache: Add reference counter to cache operations Signed-off-by: Thomas Graf --- include/netlink/cache-api.h | 6 ++++++ lib/cache_mngt.c | 32 +++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/netlink/cache-api.h b/include/netlink/cache-api.h index dd42671..f2111b9 100644 --- a/include/netlink/cache-api.h +++ b/include/netlink/cache-api.h @@ -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 diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c index 65c4707..d0dfcdd 100644 --- a/lib/cache_mngt.c +++ b/lib/cache_mngt.c @@ -50,6 +50,24 @@ struct nl_cache_ops *__nl_cache_ops_lookup(const char *name) } /** + * 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; } /** @} */ -- cgit v0.12