From: Bradley Nicholes
Date: Wed, 11 Feb 2004 18:07:46 +0000 (+0000)
Subject: Fix the shared memory caching issues in util_ldap PR #18756
X-Git-Tag: 2.0.49~111
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=813c28c25eba91c18a2487deea1d44d8af710b51;p=thirdparty%2Fapache%2Fhttpd.git
Fix the shared memory caching issues in util_ldap PR #18756
Submitted by: Matthieu Estrade, Brad Nicholes
Reviewed by: Mathieu Estrade, Brad Nicholes, Jeff Trawick
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@102632 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index e2d178b6e1b..dff81bf84d3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
Changes with Apache 2.0.49
+ *) mod_auth_ldap: Fix some segfaults in the cache logic. PR 18756.
+ [Matthieu Estrade , Brad Nicholes]
+
*) mod_cgid: Restart the cgid daemon if it crashes. PR 19849
[Glenn Nielsen ]
diff --git a/STATUS b/STATUS
index 53c3d0ca6d1..e5edeb72f24 100644
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
APACHE 2.0 STATUS: -*-text-*-
-Last modified at [$Date: 2004/02/10 14:53:27 $]
+Last modified at [$Date: 2004/02/11 18:07:45 $]
Release:
@@ -230,17 +230,6 @@ PATCHES TO BACKPORT FROM 2.1
nd replies: But if it can't be 0 the alternatives thereafter make no
sense anymore, right?
- * LDAP cache fixes from Matthieu Estrade; see PR 18756
- include/util_ldap.h r1.12
- modules/experimental/util_ldap.c r1.15, r1.16
- modules/experimental/util_ldap_cache.c r1.9, r1.10
- modules/experimental/util_ldap_cache.h r1.7, r1.8
- modules/experimental/util_ldap_cache_mgr.c r1.6, r1.7, r1.8, r1.10
- +1: trawick (this stuff can sure use more eyes, but some users
- have already tested the patch successfully)
- bnicholes (looks good on Netware but then NetWare does not
- use shared memory.)
-
* mod_auth_digest: Allow sub-requests with different methods than the
original request. PR 25040.
modules/aaa/mod_auth_digest.c: r1.82
diff --git a/include/util_ldap.h b/include/util_ldap.h
index 38f4944228e..4f9c24f8cdb 100644
--- a/include/util_ldap.h
+++ b/include/util_ldap.h
@@ -36,6 +36,10 @@
#include "http_protocol.h"
#include "http_request.h"
+#if APR_HAS_SHARED_MEMORY
+#include "apr_rmm.h"
+#include "apr_shm.h"
+#endif
/* Create a set of LDAP_DECLARE(type), LDLDAP_DECLARE(type) and
* LDAP_DECLARE_DATA with appropriate export and import tags for the platform
@@ -58,7 +62,6 @@
#define LDAP_DECLARE_DATA __declspec(dllimport)
#endif
-
/*
* LDAP Connections
*/
@@ -99,9 +102,11 @@ typedef struct util_ldap_state_t {
apr_pool_t *pool; /* pool from which this state is allocated */
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex; /* mutex lock for the connection list */
+ apr_thread_rwlock_t *util_ldap_cache_lock;
#endif
apr_size_t cache_bytes; /* Size (in bytes) of shared memory cache */
+ char *cache_file; /* filename for shm */
long search_cache_ttl; /* TTL for search cache */
long search_cache_size; /* Size (in entries) of search cache */
long compare_cache_ttl; /* TTL for compare cache */
@@ -111,6 +116,15 @@ typedef struct util_ldap_state_t {
char *cert_auth_file;
int cert_file_type;
int ssl_support;
+
+#if APR_HAS_SHARED_MEMORY
+ apr_shm_t *cache_shm;
+ apr_rmm_t *cache_rmm;
+#endif
+
+ /* cache ald */
+ void *util_ldap_cache;
+
} util_ldap_state_t;
@@ -247,21 +261,21 @@ LDAP_DECLARE(int) util_ldap_ssl_supported(request_rec *r);
* @param reqsize The size of the shared memory segement to request. A size
* of zero requests the max size possible from
* apr_shmem_init()
- * @deffunc void util_ldap_cache_init(apr_pool_t *p)
+ * @deffunc void util_ldap_cache_init(apr_pool_t *p, util_ldap_state_t *st)
* @return The status code returned is the status code of the
* apr_smmem_init() call. Regardless of the status, the cache
* will be set up at least for in-process or in-thread operation.
*/
-apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize);
+apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st);
/**
* Display formatted stats for cache
* @param The pool to allocate the returned string from
* @tip This function returns a string allocated from the provided pool that describes
* various stats about the cache.
- * @deffunc char *util_ald_cache_display(apr_pool_t *pool)
+ * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
*/
-char *util_ald_cache_display(apr_pool_t *pool);
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st);
/* from apr_ldap_cache_mgr.c */
@@ -271,9 +285,9 @@ char *util_ald_cache_display(apr_pool_t *pool);
* @param The pool to allocate the returned string from
* @tip This function returns a string allocated from the provided pool that describes
* various stats about the cache.
- * @deffunc char *util_ald_cache_display(apr_pool_t *pool)
+ * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
*/
-char *util_ald_cache_display(apr_pool_t *pool);
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st);
#endif /* APU_HAS_LDAP */
#endif /* UTIL_LDAP_H */
diff --git a/modules/experimental/util_ldap.c b/modules/experimental/util_ldap.c
index 2890abad4a1..2f2d3e1b3d7 100644
--- a/modules/experimental/util_ldap.c
+++ b/modules/experimental/util_ldap.c
@@ -102,6 +102,7 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s);
*/
int util_ldap_handler(request_rec *r)
{
+ util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
r->allowed |= (1 << M_GET);
if (r->method_number != M_GET)
@@ -132,7 +133,7 @@ int util_ldap_handler(request_rec *r)
"\n", r
);
- ap_rputs(util_ald_cache_display(r->pool), r);
+ ap_rputs(util_ald_cache_display(r->pool, st), r);
ap_rputs("\n
\n", r);
@@ -467,9 +468,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection
LDAPMessage *res, *entry;
char *searchdn;
- util_ldap_state_t *st =
- (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
- &ldap_module);
+ util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
/* read lock this function */
LDAP_CACHE_LOCK_CREATE(st->pool);
@@ -478,7 +477,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection
LDAP_CACHE_WRLOCK();
curnode.url = url;
- curl = util_ald_cache_fetch(util_ldap_cache, &curnode);
+ curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
if (curl == NULL) {
curl = util_ald_create_caches(st, url);
}
@@ -598,7 +597,7 @@ LDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t
/* get cache entry (or create one) */
LDAP_CACHE_WRLOCK();
curnode.url = url;
- curl = util_ald_cache_fetch(util_ldap_cache, &curnode);
+ curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
if (curl == NULL) {
curl = util_ald_create_caches(st, url);
}
@@ -721,7 +720,7 @@ LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connecti
/* Get the cache node for this url */
LDAP_CACHE_WRLOCK();
curnode.url = url;
- curl = (util_url_node_t *)util_ald_cache_fetch(util_ldap_cache, &curnode);
+ curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, &curnode);
if (curl == NULL) {
curl = util_ald_create_caches(st, url);
}
@@ -923,6 +922,26 @@ static const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy, const
return NULL;
}
+static const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy, const char *file)
+{
+ util_ldap_state_t *st =
+ (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
+ &ldap_module);
+
+ if (file) {
+ st->cache_file = ap_server_root_relative(st->pool, file);
+ }
+ else {
+ st->cache_file = NULL;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
+ "LDAP cache: Setting shared memory cache file to %s bytes.",
+ st->cache_file);
+
+ return NULL;
+}
+
static const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, const char *ttl)
{
util_ldap_state_t *st =
@@ -1052,22 +1071,6 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
return st;
}
-static void util_ldap_init_module(apr_pool_t *pool, server_rec *s)
-{
- util_ldap_state_t *st =
- (util_ldap_state_t *)ap_get_module_config(s->module_config,
- &ldap_module);
-
- apr_status_t result = util_ldap_cache_init(pool, st->cache_bytes);
- char buf[MAX_STRING_LEN];
-
- apr_strerror(result, buf, sizeof(buf));
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s,
- "[%d] ldap cache init: %s",
- getpid(), buf);
-}
-
-
static apr_status_t util_ldap_cleanup_module(void *data)
{
server_rec *s = data;
@@ -1089,13 +1092,46 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
int rc = LDAP_SUCCESS;
+ apr_status_t result;
+ char buf[MAX_STRING_LEN];
- util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
- s->module_config,
- &ldap_module);
+ util_ldap_state_t *st =
+ (util_ldap_state_t *)ap_get_module_config(s->module_config, &ldap_module);
- /* log the LDAP SDK used
- */
+#if APR_HAS_SHARED_MEMORY
+ server_rec *s_vhost;
+ util_ldap_state_t *st_vhost;
+
+ /* initializing cache if file is here and we already don't have shm addr*/
+ if (st->cache_file && !st->cache_shm) {
+#endif
+ result = util_ldap_cache_init(p, st);
+ apr_strerror(result, buf, sizeof(buf));
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s,
+ "LDAP cache init: %s", buf);
+
+#if APR_HAS_SHARED_MEMORY
+ /* merge config in all vhost */
+ s_vhost = s->next;
+ while (s_vhost) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s,
+ "LDAP merging Shared Cache conf: shm=0x%x rmm=0x%x for VHOST: %s",
+ st->cache_shm, st->cache_rmm, s_vhost->server_hostname);
+
+ st_vhost = (util_ldap_state_t *)ap_get_module_config(s_vhost->module_config, &ldap_module);
+ st_vhost->cache_shm = st->cache_shm;
+ st_vhost->cache_rmm = st->cache_rmm;
+ st_vhost->cache_file = st->cache_file;
+ s_vhost = s_vhost->next;
+ }
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0 , s, "LDAP cache: Unable to init Shared Cache: no file");
+ }
+#endif
+
+ /* log the LDAP SDK used
+ */
#if APR_HAS_NETSCAPE_LDAPSDK
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
@@ -1258,6 +1294,10 @@ command_rec util_ldap_cmds[] = {
"Sets the size of the shared memory cache in bytes. "
"Zero means disable the shared memory cache. Defaults to 100KB."),
+ AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file, NULL, RSRC_CONF,
+ "Sets the file of the shared memory cache."
+ "Nothing means disable the shared memory cache."),
+
AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries, NULL, RSRC_CONF,
"Sets the maximum number of entries that are possible in the LDAP "
"search cache. "
@@ -1292,7 +1332,6 @@ command_rec util_ldap_cmds[] = {
static void util_ldap_register_hooks(apr_pool_t *p)
{
ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
- ap_hook_child_init(util_ldap_init_module, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
diff --git a/modules/experimental/util_ldap_cache.c b/modules/experimental/util_ldap_cache.c
index f7f333c6841..a279a57e010 100644
--- a/modules/experimental/util_ldap_cache.c
+++ b/modules/experimental/util_ldap_cache.c
@@ -27,8 +27,9 @@
#ifdef APU_HAS_LDAP
+#if APR_HAS_SHARED_MEMORY
#define MODLDAP_SHMEM_CACHE "/tmp/mod_ldap_cache"
-
+#endif
/* ------------------------------------------------------------------ */
@@ -46,14 +47,14 @@ int util_ldap_url_node_compare(void *a, void *b)
return(strcmp(na->url, nb->url) == 0);
}
-void *util_ldap_url_node_copy(void *c)
+void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c)
{
util_url_node_t *n = (util_url_node_t *)c;
- util_url_node_t *node = (util_url_node_t *)util_ald_alloc(sizeof(util_url_node_t));
+ util_url_node_t *node = (util_url_node_t *)util_ald_alloc(cache, sizeof(util_url_node_t));
if (node) {
- if (!(node->url = util_ald_strdup(n->url))) {
- util_ald_free(node->url);
+ if (!(node->url = util_ald_strdup(cache, n->url))) {
+ util_ald_free(cache, node->url);
return NULL;
}
node->search_cache = n->search_cache;
@@ -66,15 +67,15 @@ void *util_ldap_url_node_copy(void *c)
}
}
-void util_ldap_url_node_free(void *n)
+void util_ldap_url_node_free(util_ald_cache_t *cache, void *n)
{
util_url_node_t *node = (util_url_node_t *)n;
- util_ald_free(node->url);
+ util_ald_free(cache, node->url);
util_ald_destroy_cache(node->search_cache);
util_ald_destroy_cache(node->compare_cache);
util_ald_destroy_cache(node->dn_compare_cache);
- util_ald_free(node);
+ util_ald_free(cache, node);
}
/* ------------------------------------------------------------------ */
@@ -92,10 +93,10 @@ int util_ldap_search_node_compare(void *a, void *b)
((util_search_node_t *)b)->username) == 0);
}
-void *util_ldap_search_node_copy(void *c)
+void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c)
{
util_search_node_t *node = (util_search_node_t *)c;
- util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t));
+ util_search_node_t *newnode = util_ald_alloc(cache, sizeof(util_search_node_t));
/* safety check */
if (newnode) {
@@ -105,13 +106,13 @@ void *util_ldap_search_node_copy(void *c)
int k = 0;
int i = 0;
while (node->vals[k++]);
- if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) {
- util_ldap_search_node_free(newnode);
+ if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) {
+ util_ldap_search_node_free(cache, newnode);
return NULL;
}
while (node->vals[i]) {
- if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) {
- util_ldap_search_node_free(newnode);
+ if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) {
+ util_ldap_search_node_free(cache, newnode);
return NULL;
}
i++;
@@ -120,10 +121,10 @@ void *util_ldap_search_node_copy(void *c)
else {
newnode->vals = NULL;
}
- if (!(newnode->username = util_ald_strdup(node->username)) ||
- !(newnode->dn = util_ald_strdup(node->dn)) ||
- !(newnode->bindpw = util_ald_strdup(node->bindpw)) ) {
- util_ldap_search_node_free(newnode);
+ if (!(newnode->username = util_ald_strdup(cache, node->username)) ||
+ !(newnode->dn = util_ald_strdup(cache, node->dn)) ||
+ !(newnode->bindpw = util_ald_strdup(cache, node->bindpw)) ) {
+ util_ldap_search_node_free(cache, newnode);
return NULL;
}
newnode->lastbind = node->lastbind;
@@ -132,20 +133,20 @@ void *util_ldap_search_node_copy(void *c)
return (void *)newnode;
}
-void util_ldap_search_node_free(void *n)
+void util_ldap_search_node_free(util_ald_cache_t *cache, void *n)
{
int i = 0;
util_search_node_t *node = (util_search_node_t *)n;
if (node->vals) {
while (node->vals[i]) {
- util_ald_free(node->vals[i++]);
+ util_ald_free(cache, node->vals[i++]);
}
- util_ald_free(node->vals);
+ util_ald_free(cache, node->vals);
}
- util_ald_free(node->username);
- util_ald_free(node->dn);
- util_ald_free(node->bindpw);
- util_ald_free(node);
+ util_ald_free(cache, node->username);
+ util_ald_free(cache, node->dn);
+ util_ald_free(cache, node->bindpw);
+ util_ald_free(cache, node);
}
/* ------------------------------------------------------------------ */
@@ -165,16 +166,16 @@ int util_ldap_compare_node_compare(void *a, void *b)
strcmp(na->value, nb->value) == 0);
}
-void *util_ldap_compare_node_copy(void *c)
+void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c)
{
util_compare_node_t *n = (util_compare_node_t *)c;
- util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(sizeof(util_compare_node_t));
+ util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(cache, sizeof(util_compare_node_t));
if (node) {
- if (!(node->dn = util_ald_strdup(n->dn)) ||
- !(node->attrib = util_ald_strdup(n->attrib)) ||
- !(node->value = util_ald_strdup(n->value))) {
- util_ldap_compare_node_free(node);
+ if (!(node->dn = util_ald_strdup(cache, n->dn)) ||
+ !(node->attrib = util_ald_strdup(cache, n->attrib)) ||
+ !(node->value = util_ald_strdup(cache, n->value))) {
+ util_ldap_compare_node_free(cache, node);
return NULL;
}
node->lastcompare = n->lastcompare;
@@ -186,13 +187,13 @@ void *util_ldap_compare_node_copy(void *c)
}
}
-void util_ldap_compare_node_free(void *n)
+void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n)
{
util_compare_node_t *node = (util_compare_node_t *)n;
- util_ald_free(node->dn);
- util_ald_free(node->attrib);
- util_ald_free(node->value);
- util_ald_free(node);
+ util_ald_free(cache, node->dn);
+ util_ald_free(cache, node->attrib);
+ util_ald_free(cache, node->value);
+ util_ald_free(cache, node);
}
/* ------------------------------------------------------------------ */
@@ -208,14 +209,14 @@ int util_ldap_dn_compare_node_compare(void *a, void *b)
((util_dn_compare_node_t *)b)->reqdn) == 0);
}
-void *util_ldap_dn_compare_node_copy(void *c)
+void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c)
{
util_dn_compare_node_t *n = (util_dn_compare_node_t *)c;
- util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(sizeof(util_dn_compare_node_t));
+ util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(cache, sizeof(util_dn_compare_node_t));
if (node) {
- if (!(node->reqdn = util_ald_strdup(n->reqdn)) ||
- !(node->dn = util_ald_strdup(n->dn))) {
- util_ldap_dn_compare_node_free(node);
+ if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) ||
+ !(node->dn = util_ald_strdup(cache, n->dn))) {
+ util_ldap_dn_compare_node_free(cache, node);
return NULL;
}
return node;
@@ -225,12 +226,12 @@ void *util_ldap_dn_compare_node_copy(void *c)
}
}
-void util_ldap_dn_compare_node_free(void *n)
+void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n)
{
util_dn_compare_node_t *node = (util_dn_compare_node_t *)n;
- util_ald_free(node->reqdn);
- util_ald_free(node->dn);
- util_ald_free(node);
+ util_ald_free(cache, node->reqdn);
+ util_ald_free(cache, node->dn);
+ util_ald_free(cache, node);
}
@@ -240,46 +241,53 @@ apr_status_t util_ldap_cache_module_kill(void *data);
apr_status_t util_ldap_cache_module_kill(void *data)
{
+ util_ldap_state_t *st = (util_ldap_state_t *)data;
+
#if APR_HAS_SHARED_MEMORY
- if (util_ldap_shm != NULL) {
- apr_status_t result = apr_shm_destroy(util_ldap_shm);
- util_ldap_shm = NULL;
+ if (st->cache_shm != NULL) {
+ apr_status_t result = apr_shm_destroy(st->cache_shm);
+ st->cache_shm = NULL;
+ apr_file_remove(st->cache_file, st->pool);
return result;
}
#endif
- util_ald_destroy_cache(util_ldap_cache);
+ util_ald_destroy_cache(st->util_ldap_cache);
return APR_SUCCESS;
}
-apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize)
+apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
{
#if APR_HAS_SHARED_MEMORY
apr_status_t result;
- result = apr_shm_create(&util_ldap_shm, reqsize, MODLDAP_SHMEM_CACHE, pool);
+ if (!st->cache_file) {
+ return -1;
+ }
+
+ result = apr_shm_create(&st->cache_shm, st->cache_bytes, st->cache_file, st->pool);
if (result == EEXIST) {
/*
* The cache could have already been created (i.e. we may be a child process). See
* if we can attach to the existing shared memory
*/
- result = apr_shm_attach(&util_ldap_shm, MODLDAP_SHMEM_CACHE, pool);
+ result = apr_shm_attach(&st->cache_shm, st->cache_file, st->pool);
}
if (result != APR_SUCCESS) {
return result;
}
/* This will create a rmm "handler" to get into the shared memory area */
- apr_rmm_init(&util_ldap_rmm, NULL,
- (void *)apr_shm_baseaddr_get(util_ldap_shm), reqsize, pool);
+ apr_rmm_init(&st->cache_rmm, NULL, (void *)apr_shm_baseaddr_get(st->cache_shm), st->cache_bytes, st->pool);
#endif
- apr_pool_cleanup_register(pool, NULL, util_ldap_cache_module_kill, apr_pool_cleanup_null);
+ apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null);
- util_ldap_cache = util_ald_create_cache(50,
- util_ldap_url_node_hash,
- util_ldap_url_node_compare,
- util_ldap_url_node_copy,
- util_ldap_url_node_free);
+ st->util_ldap_cache =
+ util_ald_create_cache(st,
+ util_ldap_url_node_hash,
+ util_ldap_url_node_compare,
+ util_ldap_url_node_copy,
+ util_ldap_url_node_free);
return APR_SUCCESS;
}
diff --git a/modules/experimental/util_ldap_cache.h b/modules/experimental/util_ldap_cache.h
index 3fb680ef87c..2b16fcca6bd 100644
--- a/modules/experimental/util_ldap_cache.h
+++ b/modules/experimental/util_ldap_cache.h
@@ -28,8 +28,10 @@
* LDAP Cache Manager
*/
+#if APR_HAS_SHARED_MEMORY
#include
#include /* EDD */
+#endif
typedef struct util_cache_node_t {
void *payload; /* Pointer to the payload */
@@ -37,47 +39,48 @@ typedef struct util_cache_node_t {
struct util_cache_node_t *next;
} util_cache_node_t;
-typedef struct util_ald_cache_t {
- unsigned long size; /* Size of cache array */
- unsigned long maxentries; /* Maximum number of cache entries */
- unsigned long numentries; /* Current number of cache entries */
- unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */
- apr_time_t marktime; /* Time that the cache became 3/4 full */
- unsigned long (*hash)(void *); /* Func to hash the payload */
- int (*compare)(void *, void *); /* Func to compare two payloads */
- void * (*copy)(void *); /* Func to alloc mem and copy payload to new mem */
- void (*free)(void *); /* Func to free mem used by the payload */
+typedef struct util_ald_cache util_ald_cache_t;
+
+struct util_ald_cache {
+ unsigned long size; /* Size of cache array */
+ unsigned long maxentries; /* Maximum number of cache entries */
+ unsigned long numentries; /* Current number of cache entries */
+ unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */
+ apr_time_t marktime; /* Time that the cache became 3/4 full */
+ unsigned long (*hash)(void *); /* Func to hash the payload */
+ int (*compare)(void *, void *); /* Func to compare two payloads */
+ void * (*copy)(util_ald_cache_t *cache, void *); /* Func to alloc mem and copy payload to new mem */
+ void (*free)(util_ald_cache_t *cache, void *); /* Func to free mem used by the payload */
util_cache_node_t **nodes;
- unsigned long numpurges; /* No. of times the cache has been purged */
- double avg_purgetime; /* Average time to purge the cache */
- apr_time_t last_purge; /* Time of the last purge */
- unsigned long npurged; /* Number of elements purged in last purge. This is not
- obvious: it won't be 3/4 the size of the cache if
- there were a lot of expired entries. */
+ unsigned long numpurges; /* No. of times the cache has been purged */
+ double avg_purgetime; /* Average time to purge the cache */
+ apr_time_t last_purge; /* Time of the last purge */
+ unsigned long npurged; /* Number of elements purged in last purge. This is not
+ obvious: it won't be 3/4 the size of the cache if
+ there were a lot of expired entries. */
- unsigned long fetches; /* Number of fetches */
- unsigned long hits; /* Number of cache hits */
- unsigned long inserts; /* Number of inserts */
- unsigned long removes; /* Number of removes */
-} util_ald_cache_t;
+ unsigned long fetches; /* Number of fetches */
+ unsigned long hits; /* Number of cache hits */
+ unsigned long inserts; /* Number of inserts */
+ unsigned long removes; /* Number of removes */
#if APR_HAS_SHARED_MEMORY
-apr_shm_t *util_ldap_shm;
-apr_rmm_t *util_ldap_rmm;
+ apr_shm_t *shm_addr;
+ apr_rmm_t *rmm_addr;
#endif
-util_ald_cache_t *util_ldap_cache;
+
+};
#if APR_HAS_THREADS
-apr_thread_rwlock_t *util_ldap_cache_lock;
#define LDAP_CACHE_LOCK_CREATE(p) \
- if (!util_ldap_cache_lock) apr_thread_rwlock_create(&util_ldap_cache_lock, p)
+ if (!st->util_ldap_cache_lock) apr_thread_rwlock_create(&st->util_ldap_cache_lock, st->pool)
#define LDAP_CACHE_WRLOCK() \
- apr_thread_rwlock_wrlock(util_ldap_cache_lock)
+ apr_thread_rwlock_wrlock(st->util_ldap_cache_lock)
#define LDAP_CACHE_UNLOCK() \
- apr_thread_rwlock_unlock(util_ldap_cache_lock)
+ apr_thread_rwlock_unlock(st->util_ldap_cache_lock)
#define LDAP_CACHE_RDLOCK() \
- apr_thread_rwlock_rdlock(util_ldap_cache_lock)
+ apr_thread_rwlock_rdlock(st->util_ldap_cache_lock)
#else
#define LDAP_CACHE_LOCK_CREATE(p)
#define LDAP_CACHE_WRLOCK()
@@ -152,35 +155,39 @@ typedef struct util_dn_compare_node_t {
/* util_ldap_cache.c */
unsigned long util_ldap_url_node_hash(void *n);
int util_ldap_url_node_compare(void *a, void *b);
-void *util_ldap_url_node_copy(void *c);
-void util_ldap_url_node_free(void *n);
+void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_url_node_free(util_ald_cache_t *cache, void *n);
unsigned long util_ldap_search_node_hash(void *n);
int util_ldap_search_node_compare(void *a, void *b);
-void *util_ldap_search_node_copy(void *c);
-void util_ldap_search_node_free(void *n);
+void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_search_node_free(util_ald_cache_t *cache, void *n);
unsigned long util_ldap_compare_node_hash(void *n);
int util_ldap_compare_node_compare(void *a, void *b);
-void *util_ldap_compare_node_copy(void *c);
-void util_ldap_compare_node_free(void *n);
+void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n);
unsigned long util_ldap_dn_compare_node_hash(void *n);
int util_ldap_dn_compare_node_compare(void *a, void *b);
-void *util_ldap_dn_compare_node_copy(void *c);
-void util_ldap_dn_compare_node_free(void *n);
+void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n);
/* util_ldap_cache_mgr.c */
-void util_ald_free(const void *ptr);
-void *util_ald_alloc(unsigned long size);
-const char *util_ald_strdup(const char *s);
+/* Cache alloc and free function, dealing or not with shm */
+void util_ald_free(util_ald_cache_t *cache, const void *ptr);
+void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size);
+const char *util_ald_strdup(util_ald_cache_t *cache, const char *s);
+
+/* Cache managing function */
unsigned long util_ald_hash_string(int nstr, ...);
void util_ald_cache_purge(util_ald_cache_t *cache);
util_url_node_t *util_ald_create_caches(util_ldap_state_t *s, const char *url);
-util_ald_cache_t *util_ald_create_cache(unsigned long maxentries,
+util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
unsigned long (*hashfunc)(void *),
int (*comparefunc)(void *, void *),
- void * (*copyfunc)(void *),
- void (*freefunc)(void *));
+ void * (*copyfunc)(util_ald_cache_t *cache, void *),
+ void (*freefunc)(util_ald_cache_t *cache, void *));
+
void util_ald_destroy_cache(util_ald_cache_t *cache);
void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload);
void util_ald_cache_insert(util_ald_cache_t *cache, void *payload);
diff --git a/modules/experimental/util_ldap_cache_mgr.c b/modules/experimental/util_ldap_cache_mgr.c
index a8f794ef892..3706514e150 100644
--- a/modules/experimental/util_ldap_cache_mgr.c
+++ b/modules/experimental/util_ldap_cache_mgr.c
@@ -73,14 +73,17 @@ static const unsigned long primes[] =
0
};
-void util_ald_free(const void *ptr)
+void util_ald_free(util_ald_cache_t *cache, const void *ptr)
{
#if APR_HAS_SHARED_MEMORY
- if (util_ldap_shm) {
+ if (cache->rmm_addr) {
if (ptr)
- apr_rmm_free(util_ldap_rmm, apr_rmm_offset_get(util_ldap_rmm, (void *)ptr));
- } else {
+ /* Free in shared memory */
+ apr_rmm_free(cache->rmm_addr, apr_rmm_offset_get(cache->rmm_addr, (void *)ptr));
+ }
+ else {
if (ptr)
+ /* Cache shm is not used */
free((void *)ptr);
}
#else
@@ -89,14 +92,17 @@ void util_ald_free(const void *ptr)
#endif
}
-void *util_ald_alloc(unsigned long size)
+void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size)
{
if (0 == size)
return NULL;
#if APR_HAS_SHARED_MEMORY
- if (util_ldap_shm) {
- return (void *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, size));
- } else {
+ if (cache->rmm_addr) {
+ /* allocate from shared memory */
+ return (void *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, size));
+ }
+ else {
+ /* Cache shm is not used */
return (void *)calloc(sizeof(char), size);
}
#else
@@ -104,11 +110,12 @@ void *util_ald_alloc(unsigned long size)
#endif
}
-const char *util_ald_strdup(const char *s)
+const char *util_ald_strdup(util_ald_cache_t *cache, const char *s)
{
#if APR_HAS_SHARED_MEMORY
- if (util_ldap_shm) {
- char *buf = (char *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, strlen(s)+1));
+ if (cache->rmm_addr) {
+ /* allocate from shared memory */
+ char *buf = (char *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, strlen(s)+1));
if (buf) {
strcpy(buf, s);
return buf;
@@ -117,6 +124,7 @@ const char *util_ald_strdup(const char *s)
return NULL;
}
} else {
+ /* Cache shm is not used */
return strdup(s);
}
#else
@@ -178,8 +186,8 @@ void util_ald_cache_purge(util_ald_cache_t *cache)
while (p != NULL) {
if (p->add_time < cache->marktime) {
q = p->next;
- (*cache->free)(p->payload);
- util_ald_free(p);
+ (*cache->free)(cache, p->payload);
+ util_ald_free(cache, p);
cache->numentries--;
cache->npurged++;
p = q;
@@ -208,17 +216,17 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
util_ald_cache_t *dn_compare_cache;
/* create the three caches */
- search_cache = util_ald_create_cache(st->search_cache_size,
+ search_cache = util_ald_create_cache(st,
util_ldap_search_node_hash,
util_ldap_search_node_compare,
util_ldap_search_node_copy,
util_ldap_search_node_free);
- compare_cache = util_ald_create_cache(st->compare_cache_size,
+ compare_cache = util_ald_create_cache(st,
util_ldap_compare_node_hash,
util_ldap_compare_node_compare,
util_ldap_compare_node_copy,
util_ldap_compare_node_free);
- dn_compare_cache = util_ald_create_cache(st->compare_cache_size,
+ dn_compare_cache = util_ald_create_cache(st,
util_ldap_dn_compare_node_hash,
util_ldap_dn_compare_node_compare,
util_ldap_dn_compare_node_copy,
@@ -233,7 +241,7 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
curl->compare_cache = compare_cache;
curl->dn_compare_cache = dn_compare_cache;
- util_ald_cache_insert(util_ldap_cache, curl);
+ util_ald_cache_insert(st->util_ldap_cache, curl);
}
@@ -241,32 +249,36 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
}
-util_ald_cache_t *util_ald_create_cache(unsigned long maxentries,
+util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
unsigned long (*hashfunc)(void *),
int (*comparefunc)(void *, void *),
- void * (*copyfunc)(void *),
- void (*freefunc)(void *))
+ void * (*copyfunc)(util_ald_cache_t *cache, void *),
+ void (*freefunc)(util_ald_cache_t *cache, void *))
{
util_ald_cache_t *cache;
unsigned long i;
- if (maxentries <= 0)
+ if (st->search_cache_size <= 0)
return NULL;
- cache = (util_ald_cache_t *)util_ald_alloc(sizeof(util_ald_cache_t));
+#if APR_HAS_SHARED_MEMORY
+ cache = (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t)));
+#else
+ cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1);
+#endif
if (!cache)
return NULL;
- cache->maxentries = maxentries;
+ cache->maxentries = st->search_cache_size;
cache->numentries = 0;
- cache->size = maxentries / 3;
+ cache->size = st->search_cache_size / 3;
if (cache->size < 64) cache->size = 64;
for (i = 0; primes[i] && primes[i] < cache->size; ++i) ;
cache->size = primes[i]? primes[i] : primes[i-1];
- cache->nodes = (util_cache_node_t **)util_ald_alloc(cache->size * sizeof(util_cache_node_t *));
+ cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *));
if (!cache->nodes) {
- util_ald_free(cache);
+ util_ald_free(cache, cache);
return NULL;
}
@@ -306,13 +318,13 @@ void util_ald_destroy_cache(util_ald_cache_t *cache)
q = NULL;
while (p != NULL) {
q = p->next;
- (*cache->free)(p->payload);
- util_ald_free(p);
+ (*cache->free)(cache, p->payload);
+ util_ald_free(cache, p);
p = q;
}
}
- util_ald_free(cache->nodes);
- util_ald_free(cache);
+ util_ald_free(cache, cache->nodes);
+ util_ald_free(cache, cache);
}
void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload)
@@ -351,11 +363,13 @@ void util_ald_cache_insert(util_ald_cache_t *cache, void *payload)
if (cache == NULL || payload == NULL)
return;
+ if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL)
+ return;
+
cache->inserts++;
hashval = (*cache->hash)(payload) % cache->size;
- node = (util_cache_node_t *)util_ald_alloc(sizeof(util_cache_node_t));
node->add_time = apr_time_now();
- node->payload = (*cache->copy)(payload);
+ node->payload = (*cache->copy)(cache, payload);
node->next = cache->nodes[hashval];
cache->nodes[hashval] = node;
if (++cache->numentries == cache->fullmark)
@@ -392,8 +406,8 @@ void util_ald_cache_remove(util_ald_cache_t *cache, void *payload)
/* We found the node and it's not the first in the list */
q->next = p->next;
}
- (*cache->free)(p->payload);
- util_ald_free(p);
+ (*cache->free)(cache, p->payload);
+ util_ald_free(cache, p);
cache->numentries--;
}
@@ -460,16 +474,19 @@ char *util_ald_cache_display_stats(apr_pool_t *p, util_ald_cache_t *cache, char
return buf;
}
-char *util_ald_cache_display(apr_pool_t *pool)
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
{
unsigned long i;
char *buf, *t1, *t2, *t3;
+ util_ald_cache_t *util_ldap_cache = st->util_ldap_cache;
+
+
if (!util_ldap_cache) {
return "Cache has not been enabled/initialised. |
";
}
- buf = util_ald_cache_display_stats(pool, util_ldap_cache, "LDAP URL Cache");
+ buf = util_ald_cache_display_stats(pool, st->util_ldap_cache, "LDAP URL Cache");
for (i=0; i < util_ldap_cache->size; ++i) {
util_cache_node_t *p;