else {
if (curl) {
/* compare successful - add to the compare cache */
- LDAP_CACHE_RDLOCK();
+ LDAP_CACHE_WRLOCK();
newnode.reqdn = (char *)reqdn;
newnode.dn = (char *)dn;
- util_ald_cache_insert(curl->dn_compare_cache, &newnode);
+
+ node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
+ if ((node == NULL) ||
+ (strcmp(reqdn, node->reqdn) != 0) || (strcmp(dn, node->dn) != 0)) {
+
+ util_ald_cache_insert(curl->dn_compare_cache, &newnode);
+ }
LDAP_CACHE_UNLOCK();
}
ldc->reason = "DN Comparison TRUE (checked on server)";
LDAP_CACHE_WRLOCK();
the_compare_node.lastcompare = curtime;
the_compare_node.result = result;
- util_ald_cache_insert(curl->compare_cache, &the_compare_node);
+
+ /* If the node doesn't exist then insert it, otherwise just update it with
+ the last results */
+ compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node);
+ if ((compare_nodep == NULL) ||
+ (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) ||
+ (strcmp(the_compare_node.attrib, compare_nodep->attrib) != 0) ||
+ (strcmp(the_compare_node.value, compare_nodep->value) != 0)) {
+
+ util_ald_cache_insert(curl->compare_cache, &the_compare_node);
+ }
+ else {
+ compare_nodep->lastcompare = curtime;
+ compare_nodep->result = result;
+ }
LDAP_CACHE_UNLOCK();
}
if (LDAP_COMPARE_TRUE == result) {
the_search_node.bindpw = bindpw;
the_search_node.lastbind = apr_time_now();
the_search_node.vals = vals;
- util_ald_cache_insert(curl->search_cache, &the_search_node);
+
+ /* Search again to make sure that another thread didn't ready insert this node
+ into the cache before we got here. If it does exist then update the lastbind */
+ search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node);
+ if ((search_nodep == NULL) ||
+ (strcmp(*binddn, search_nodep->dn) != 0) || (strcmp(bindpw, search_nodep->bindpw) != 0)) {
+
+ util_ald_cache_insert(curl->search_cache, &the_search_node);
+ }
+ else {
+ search_nodep->lastbind = the_search_node.lastbind;
+ }
LDAP_CACHE_UNLOCK();
}
ldap_msgfree(res);
for (p = str; *p; ++p) {
h = ( h << 4 ) + *p;
if ( ( g = h & 0xf0000000 ) ) {
- h = h ^ (g >> 24);
- h = h ^ g;
+ h = h ^ (g >> 24);
+ h = h ^ g;
}
}
}
p = cache->nodes[i];
while (p != NULL) {
if (p->add_time < cache->marktime) {
- q = p->next;
- (*cache->free)(cache, p->payload);
- util_ald_free(cache, p);
- cache->numentries--;
- cache->npurged++;
- p = q;
+ q = p->next;
+ (*cache->free)(cache, p->payload);
+ util_ald_free(cache, p);
+ cache->numentries--;
+ cache->npurged++;
+ p = q;
}
else {
- p = p->next;
+ p = p->next;
}
}
}
*/
util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
{
- util_url_node_t *curl = NULL;
+ util_url_node_t curl, *newcurl;
util_ald_cache_t *search_cache;
util_ald_cache_t *compare_cache;
util_ald_cache_t *dn_compare_cache;
/* create the three caches */
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,
+ util_ldap_search_node_hash,
+ util_ldap_search_node_compare,
+ util_ldap_search_node_copy,
+ util_ldap_search_node_free,
util_ldap_search_node_display);
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,
- util_ldap_compare_node_display);
+ util_ldap_compare_node_hash,
+ util_ldap_compare_node_compare,
+ util_ldap_compare_node_copy,
+ util_ldap_compare_node_free,
+ util_ldap_compare_node_display);
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,
- util_ldap_dn_compare_node_free,
- util_ldap_dn_compare_node_display);
+ util_ldap_dn_compare_node_hash,
+ util_ldap_dn_compare_node_compare,
+ util_ldap_dn_compare_node_copy,
+ util_ldap_dn_compare_node_free,
+ util_ldap_dn_compare_node_display);
/* check that all the caches initialised successfully */
if (search_cache && compare_cache && dn_compare_cache) {
-/*XXX This can be allocated on the stack since it will be copied anyway */
- curl = (util_url_node_t *)apr_pcalloc(st->pool, sizeof(util_url_node_t));
- curl->url = url;
- curl->search_cache = search_cache;
- curl->compare_cache = compare_cache;
- curl->dn_compare_cache = dn_compare_cache;
+ /* The contents of this structure will be duplicated in shared
+ memory during the insert. So use stack memory rather than
+ pool memory to avoid a memory leak. */
+ memset (&curl, 0, sizeof(util_url_node_t));
+ curl.url = url;
+ curl.search_cache = search_cache;
+ curl.compare_cache = compare_cache;
+ curl.dn_compare_cache = dn_compare_cache;
- util_ald_cache_insert(st->util_ldap_cache, curl);
+ newcurl = util_ald_cache_insert(st->util_ldap_cache, &curl);
}
- return curl;
+ return newcurl;
}
* Insert an item into the cache.
* *** Does not catch duplicates!!! ***
*/
-void util_ald_cache_insert(util_ald_cache_t *cache, void *payload)
+void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload)
{
int hashval;
util_cache_node_t *node;
/* sanity check */
if (cache == NULL || payload == NULL) {
- return;
+ return NULL;
}
/* check if we are full - if so, try purge */
util_ald_cache_purge(cache);
if (cache->numentries >= cache->maxentries) {
/* if the purge was not effective, we leave now to avoid an overflow */
- return;
+ return NULL;
}
}
/* should be safe to add an entry */
if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) {
- return;
+ return NULL;
}
/* populate the entry */
cache->marktime=apr_time_now();
}
+ return node->payload;
}
void util_ald_cache_remove(util_ald_cache_t *cache, void *payload)