Here's one final patch to fix the global mutex crash when the global
mutex is never allocated due to disabled/empty caches.
I would really like some clarity as to whether:
- We should just stick with the single-process read/write lock for
single-worker MPMs. It would really seem so.
- Whether we should really avoid using shared memory for the LDAP
cache for single-worker MPMs. What's it really buy us in this case?
Given the patches from today and answers (and code adjustments as
appropriate) to those 2 questions, I will feel much better about the
LDAP modules as they now seem pretty stable for a wide range of
settings/circumstances -- at least on Windows. I now need to test
these on Solaris and AIX...
--
Jess Holle
Jess Holle wrote:
Sorry for the chattiness of my solution process. I've tested and these
fixes do apply with the global mutex changes *except* when one disables
caches by sizing them all to 0, Apache will crash on the first
authentication request when the global mutexes are used! This needs to
be fixed!
I've attached a unified diff containing the purge fix and the
unassigned variable fix (which as Graham pointed out is already in the
2.1 branch).
I'm still wondering if we shouldn't just stick with the local
read/write lock on Windows and other single child MPMs (NetWare?) as
this should allow better throughput in such cases and yet be safe,
right? In fact, why do we use shared memory on these platforms for the
cache? [If I'm just daft here, I apologize.]
--
Jess Holle
Jess Holle wrote:
Here's a fixed LDAP purge routine which works great in my testing (with
cache sizes of 8, 100, 1000, and 2150 and 2500 unique user logins
repeated 3 times each). [No, I haven't produced a diff as I have
pieces of util_ldap from various CVS levels at this point.]
Essentially I added all the logic surrounding 'pp', which is the
address of the previous node's 'next' field or of cache->nodes[i] in
the case of the first node. [Cleary my C is getting rusty -- this took
me a few attempts to get right...]
This fixes the biggest LDAP module issue I'm aware of: hangs and
crashes after one or more cache purges.
--- util_ldap_cache_mgr.c-2.0.51 2004-09-19 16:28:00.000000000 -0500
+++ util_ldap_cache_mgr.c 2004-09-19 16:27:56.000000000 -0500
@@ -173,7 +173,7 @@
void util_ald_cache_purge(util_ald_cache_t *cache)
{
unsigned long i;
- util_cache_node_t *p, *q;
+ util_cache_node_t *p, *q, **pp;
apr_time_t t;
if (!cache)
@@ -184,7 +184,8 @@
cache->numpurges++;
for (i=0; i < cache->size; ++i) {
- p = cache->nodes[i];
+ pp = cache->nodes + i;
+ p = *pp;
while (p != NULL) {
if (p->add_time < cache->marktime) {
q = p->next;
@@ -192,10 +193,11 @@
util_ald_free(cache, p);
cache->numentries--;
cache->npurged++;
- p = q;
+ p = *pp = q;
}
else {
- p = p->next;
+ pp = &(p->next);
+ p = *pp;
}
}
}
@@ -252,6 +254,8 @@
newcurl = util_ald_cache_insert(st->util_ldap_cache, &curl);
}
+ else
+ newcurl = NULL;
return newcurl;
}
|
--- util_ldap.c-2.0.51 2004-09-19 17:11:02.000000000 -0500
+++ util_ldap.c-new 2004-09-19 17:11:06.000000000 -0500
@@ -89,9 +89,11 @@
#endif
#define LDAP_CACHE_LOCK() \
- apr_global_mutex_lock(st->util_ldap_cache_lock)
+ if (st->util_ldap_cache_lock) \
+ apr_global_mutex_lock(st->util_ldap_cache_lock)
#define LDAP_CACHE_UNLOCK() \
- apr_global_mutex_unlock(st->util_ldap_cache_lock)
+ if (st->util_ldap_cache_lock) \
+ apr_global_mutex_unlock(st->util_ldap_cache_lock)
static void util_ldap_strdup (char **str, const char *newstr)