From 2b3912a320ef74b31d84380d91ec036dbf1b9f52 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Fri, 16 Nov 2012 00:19:38 +0100 Subject: cache: Provide safe versions of nl_cache_ops_associate() and nl_cache_ops_lookup() Signed-off-by: Thomas Graf --- include/netlink/cache.h | 2 ++ lib/cache_mngt.c | 94 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 78 insertions(+), 18 deletions(-) diff --git a/include/netlink/cache.h b/include/netlink/cache.h index 0bd4037..f193c76 100644 --- a/include/netlink/cache.h +++ b/include/netlink/cache.h @@ -106,7 +106,9 @@ extern void nl_cache_foreach_filter(struct nl_cache *, /* Cache type management */ extern struct nl_cache_ops * nl_cache_ops_lookup(const char *); +extern struct nl_cache_ops * nl_cache_ops_lookup_safe(const char *); extern struct nl_cache_ops * nl_cache_ops_associate(int, int); +extern struct nl_cache_ops * nl_cache_ops_associate_safe(int, int); extern struct nl_msgtype * nl_msgtype_lookup(struct nl_cache_ops *, int); extern void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *); extern int nl_cache_mngt_register(struct nl_cache_ops *); diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c index d0dfcdd..d5ca6d3 100644 --- a/lib/cache_mngt.c +++ b/lib/cache_mngt.c @@ -68,11 +68,13 @@ void nl_cache_ops_put(struct nl_cache_ops *ops) } /** - * Lookup the set cache operations of a certain cache type + * Lookup cache operations by name * @arg name name of the cache type * - * @return The cache operations or NULL if no operations - * have been registered under the specified name. + * @attention This function is not safe, it does not increment the reference + * counter. Please use nl_cache_ops_lookup_safe(). + * + * @return The cache operations or NULL if not found. */ struct nl_cache_ops *nl_cache_ops_lookup(const char *name) { @@ -86,38 +88,91 @@ struct nl_cache_ops *nl_cache_ops_lookup(const char *name) } /** - * Associate a message type to a set of cache operations - * @arg protocol netlink protocol - * @arg msgtype netlink message type + * Lookup cache operations by name + * @arg name name of the cache type * - * Associates the specified netlink message type with - * a registered set of cache operations. + * @note The reference counter of the returned cache operation is incremented + * and must be decremented after use with nl_cache_ops_put(). * - * @return The cache operations or NULL if no association - * could be made. + * @return The cache operations or NULL if not found. */ -struct nl_cache_ops *nl_cache_ops_associate(int protocol, int msgtype) +struct nl_cache_ops *nl_cache_ops_lookup_safe(const char *name) +{ + struct nl_cache_ops *ops; + + nl_write_lock(&cache_ops_lock); + if ((ops = __nl_cache_ops_lookup(name))) + nl_cache_ops_get(ops); + nl_write_unlock(&cache_ops_lock); + + return ops; +} + +static struct nl_cache_ops *__cache_ops_associate(int protocol, int msgtype) { int i; struct nl_cache_ops *ops; - nl_read_lock(&cache_ops_lock); for (ops = cache_ops; ops; ops = ops->co_next) { if (ops->co_protocol != protocol) continue; - for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) { - if (ops->co_msgtypes[i].mt_id == msgtype) { - nl_read_unlock(&cache_ops_lock); + for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) + if (ops->co_msgtypes[i].mt_id == msgtype) return ops; - } - } } - nl_read_unlock(&cache_ops_lock); return NULL; } +/** + * Associate protocol and message type to cache operations + * @arg protocol netlink protocol + * @arg msgtype netlink message type + * + * @attention This function is not safe, it does not increment the reference + * counter. Please use nl_cache_ops_associate_safe(). + * + * @see nl_cache_ops_associate_safe() + * + * @return The cache operations or NULL if no match found. + */ +struct nl_cache_ops *nl_cache_ops_associate(int protocol, int msgtype) +{ + struct nl_cache_ops *ops; + + nl_read_lock(&cache_ops_lock); + ops = __cache_ops_associate(protocol, msgtype); + nl_read_unlock(&cache_ops_lock); + + return ops; +} + +/** + * Associate protocol and message type to cache operations + * @arg protocol netlink protocol + * @arg msgtype netlink message type + * + * Searches the registered cache operations for a matching protocol + * and message type. + * + * @note The reference counter of the returned cache operation is incremented + * and must be decremented after use with nl_cache_ops_put(). + * + * @return The cache operations or NULL if no no match was found. + */ +struct nl_cache_ops *nl_cache_ops_associate_safe(int protocol, int msgtype) +{ + struct nl_cache_ops *ops; + + nl_write_lock(&cache_ops_lock); + if ((ops = __cache_ops_associate(protocol, msgtype))) + nl_cache_ops_get(ops); + nl_write_unlock(&cache_ops_lock); + + return ops; +} + /** * Lookup message type cache association * @arg ops cache operations @@ -126,6 +181,9 @@ struct nl_cache_ops *nl_cache_ops_associate(int protocol, int msgtype) * Searches for a matching message type association ing the specified * cache operations. * + * @attention The guranteed lifetime of the returned message type is bound + * to the lifetime of the underlying cache operations. + * * @return A message type association or NULL. */ struct nl_msgtype *nl_msgtype_lookup(struct nl_cache_ops *ops, int msgtype) -- cgit v1.2.1