From: Phil Mayers
Date: Fri, 26 Oct 2012 15:47:35 +0000 (+0100)
Subject: add locking to rlm_cache
X-Git-Tag: release_3_0_0_beta1~1644^2
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F118%2Fhead;p=thirdparty%2Ffreeradius-server.git
add locking to rlm_cache
---
diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c
index 816a2eb4e52..4fcb5696a74 100644
--- a/src/modules/rlm_cache/rlm_cache.c
+++ b/src/modules/rlm_cache/rlm_cache.c
@@ -44,6 +44,9 @@ typedef struct rlm_cache_t {
CONF_SECTION *cs;
rbtree_t *cache;
fr_heap_t *heap;
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_t cache_mutex;
+#endif
} rlm_cache_t;
typedef struct rlm_cache_entry_t {
@@ -57,6 +60,14 @@ typedef struct rlm_cache_entry_t {
VALUE_PAIR *reply;
} rlm_cache_entry_t;
+#ifdef HAVE_PTHREAD_H
+#define PTHREAD_MUTEX_LOCK pthread_mutex_lock
+#define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
+#else
+#define PTHREAD_MUTEX_LOCK(_x)
+#define PTHREAD_MUTEX_UNLOCK(_x)
+#endif
+
/*
* Compare two entries by key. There may only be one entry with
@@ -371,15 +382,16 @@ static size_t cache_xlat(void *instance, REQUEST *request,
DICT_ATTR *target;
const char *p = fmt;
char buffer[1024];
+ int ret=0;
radius_xlat(buffer, sizeof(buffer), inst->key, request, NULL, NULL);
+ PTHREAD_MUTEX_LOCK(&inst->cache_mutex);
c = cache_find(inst, request, buffer);
if (!c) {
RDEBUG("No cache entry for key \"%s\"", buffer);
-
- return 0;
+ goto done;
}
list = radius_list_name(&p, PAIR_LIST_REQUEST);
@@ -409,18 +421,20 @@ static size_t cache_xlat(void *instance, REQUEST *request,
target = dict_attrbyname(p);
if (!target) {
radlog(L_ERR, "rlm_cache: Unknown attribute \"%s\"", p);
-
- return 0;
+ goto done;
}
vp = pairfind(vps, target->attr, target->vendor);
if (!vp) {
RDEBUG("No instance of this attribute has been cached");
-
- return 0;
+ goto done;
}
- return vp_prints_value(out, freespace, vp, 0);
+ ret = vp_prints_value(out, freespace, vp, 0);
+done:
+ PTHREAD_MUTEX_UNLOCK(&inst->cache_mutex);
+ return ret;
+
}
@@ -460,6 +474,9 @@ static int cache_detach(void *instance)
fr_heap_delete(inst->heap);
rbtree_free(inst->cache);
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_destroy(&inst->cache_mutex);
+#endif
free(instance);
return 0;
}
@@ -519,6 +536,14 @@ static int cache_instantiate(CONF_SECTION *conf, void **instance)
return -1;
}
+#ifdef HAVE_PTHREAD_H
+ if (pthread_mutex_init(&inst->cache_mutex, NULL) < 0) {
+ radlog(L_ERR, "rlm_cache: Failed initializing mutex: %s", strerror(errno));
+ cache_detach(inst);
+ return -1;
+ }
+#endif
+
/*
* The cache.
*/
@@ -574,9 +599,11 @@ static int cache_it(void *instance, REQUEST *request)
rlm_cache_t *inst = instance;
VALUE_PAIR *vp;
char buffer[1024];
+ int retcode;
radius_xlat(buffer, sizeof(buffer), inst->key, request, NULL, NULL);
+ PTHREAD_MUTEX_LOCK(&inst->cache_mutex);
c = cache_find(inst, request, buffer);
/*
@@ -584,22 +611,31 @@ static int cache_it(void *instance, REQUEST *request)
*/
vp = pairfind(request->config_items, PW_CACHE_STATUS_ONLY, 0);
if (vp && vp->vp_integer) {
- return c ?
- RLM_MODULE_OK:
- RLM_MODULE_NOTFOUND;
+ if (c) {
+ retcode = RLM_MODULE_OK;
+ } else {
+ retcode = RLM_MODULE_NOTFOUND;
+ }
+ goto done;
}
if (c) {
cache_merge(inst, request, c);
- return RLM_MODULE_OK;
+ retcode = RLM_MODULE_OK;
+ goto done;
}
c = cache_add(inst, request, buffer);
- if (!c) return RLM_MODULE_NOOP;
+ if (!c) {
+ retcode = RLM_MODULE_NOOP;
+ goto done;
+ }
cache_merge(inst, request, c);
-
- return RLM_MODULE_UPDATED;
+ retcode = RLM_MODULE_UPDATED;
+done:
+ PTHREAD_MUTEX_UNLOCK(&inst->cache_mutex);
+ return retcode;
}