]> granicus.if.org Git - libnl/commitdiff
cache: Provide safe versions of nl_cache_ops_associate() and nl_cache_ops_lookup()
authorThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 23:19:38 +0000 (00:19 +0100)
committerThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 23:19:38 +0000 (00:19 +0100)
Signed-off-by: Thomas Graf <tgraf@suug.ch>
include/netlink/cache.h
lib/cache_mngt.c

index 0bd4037454cbbab8d671c4856947d90eb272fad4..f193c76c5cae659c8efb03961758e44644e604a1 100644 (file)
@@ -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 *);
index d0dfcdda63347bf9b58b4e11684b2879cd6df243..d5ca6d3c9857036bffc9c4f082a776a2f1c41f2b 100644 (file)
@@ -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)