diff options
author | Thomas Graf <tgraf@suug.ch> | 2012-11-15 23:27:51 (GMT) |
---|---|---|
committer | Thomas Graf <tgraf@suug.ch> | 2012-11-15 23:29:58 (GMT) |
commit | 235aa7ff17e12ca7a76dcfd77abfe143c2ce4dea (patch) | |
tree | a9bb6b47292db0ff3c24cda3a2f9d3b5d4ee0f41 | |
parent | cb82c2a5451a52e7365957a2325258af1b179aee (diff) | |
download | libnl-235aa7ff17e12ca7a76dcfd77abfe143c2ce4dea.zip libnl-235aa7ff17e12ca7a76dcfd77abfe143c2ce4dea.tar.gz libnl-235aa7ff17e12ca7a76dcfd77abfe143c2ce4dea.tar.bz2 |
cache: hold a reference to the cache ops while a cache is provided over it
Signed-off-by: Thomas Graf <tgraf@suug.ch>
-rw-r--r-- | lib/cache_mngt.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/cache_mngt.c b/lib/cache_mngt.c index d5ca6d3..8f011fb 100644 --- a/lib/cache_mngt.c +++ b/lib/cache_mngt.c @@ -335,6 +335,14 @@ void nl_cache_mngt_provide(struct nl_cache *cache) BUG(); else { nl_cache_get(cache); + + /* + * Hold a reference to the cache operations to ensure the + * ops don't go away while we use it to store the cache pointer. + */ + if (!ops->co_major_cache) + nl_cache_ops_get(ops); + ops->co_major_cache = cache; } @@ -360,6 +368,7 @@ void nl_cache_mngt_unprovide(struct nl_cache *cache) BUG(); else if (ops->co_major_cache == cache) { nl_cache_free(ops->co_major_cache); + nl_cache_ops_put(ops); ops->co_major_cache = NULL; } @@ -369,12 +378,15 @@ void nl_cache_mngt_unprovide(struct nl_cache *cache) struct nl_cache *__nl_cache_mngt_require(const char *name) { struct nl_cache_ops *ops; + struct nl_cache *cache = NULL; - ops = nl_cache_ops_lookup(name); - if (ops) - return ops->co_major_cache; + ops = nl_cache_ops_lookup_safe(name); + if (ops) { + cache = ops->co_major_cache; + nl_cache_ops_put(ops); + } - return NULL; + return cache; } /** |