(I originally filed this with Debian's apache team because when I searched for related information on this issue I turned up something in their bug tracker. Here is the link for more context: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=814980)
The anylock structure provided by mod_ldap was set to the type apr_anylock_none, which resulted in multiple threads mutating the shared RMM state at the same time without any concurrency guards. The issue I was seeing was that all the threads on the server were stuck inside the RMM internal function find_block_of_size every 2 or 3 days, requiring the server processes to be killed and restarted.
We are using Apache on Windows.
I made the following patch which passes in a lock to the RMM pool created in mod_ldap when APR_HAS_THREADS is defined. Since doing so we have not encountered any hangs:
(I originally filed this with Debian's apache team because when I searched for related information on this issue I turned up something in their bug tracker. Here is the link for more context: https:/ /bugs.debian. org/cgi- bin/bugreport. cgi?bug= 814980)
The anylock structure provided by mod_ldap was set to the type apr_anylock_none, which resulted in multiple threads mutating the shared RMM state at the same time without any concurrency guards. The issue I was seeing was that all the threads on the server were stuck inside the RMM internal function find_block_of_size every 2 or 3 days, requiring the server processes to be killed and restarted.
We are using Apache on Windows.
I made the following patch which passes in a lock to the RMM pool created in mod_ldap when APR_HAS_THREADS is defined. Since doing so we have not encountered any hangs:
diff -Naur httpd-2. 4.16\include\ util_ldap. h httpd-2. 4.16-ea\ include\ util_ldap. h 4.16\include\ util_ldap. h Mon Jul 14 05:07:55 2014 4.16-ea\ include\ util_ldap. h Mon Aug 29 10:20:08 2016 SHARED_ MEMORY
--- httpd-2.
+++ httpd-2.
@@ -169,6 +169,10 @@
#if APR_HAS_
apr_shm_t *cache_shm;
apr_rmm_t *cache_rmm;
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *lock;
+ apr_anylock_t cache_rmm_anylock;
+#endif
#endif
/* cache ald */ 4.16\modules\ ldap\util_ ldap_cache. c httpd-2. 4.16-ea\ modules\ ldap\util_ ldap_cache. c 4.16\modules\ ldap\util_ ldap_cache. c Mon Aug 19 04:45:19 2013 4.16-ea\ modules\ ldap\util_ ldap_cache. c Mon Aug 29 10:23:04 2016
st->cache_ shm = NULL; mutex_destroy( st->lock) ; rmm_anylock. type = apr_anylock_none; rmm_anylock. lock.pm = NULL; size_get( st->cache_ shm);
diff -Naur httpd-2.
--- httpd-2.
+++ httpd-2.
@@ -410,6 +410,14 @@
return result;
}
+
+#if APR_HAS_THREADS
+ apr_thread_
+ st->lock = NULL;
+ st->cache_
+ st->cache_
+#endif
+
#endif
return APR_SUCCESS;
}
@@ -436,8 +444,18 @@
/* Determine the usable size of the shm segment. */
size = apr_shm_
+#if APR_HAS_THREADS mutex_create( &st->lock, APR_THREAD_ MUTEX_DEFAULT, st->pool); rmm_anylock. type = apr_anylock_ threadmutex; rmm_anylock. lock.tm = st->lock; rmm_anylock. type = apr_anylock_none; rmm_anylock. lock.pm = NULL; init(&st- >cache_ rmm, NULL, init(&st- >cache_ rmm, &st->cache_ rmm_anylock,
apr_ shm_baseaddr_ get(st- >cache_ shm), size,
st-> pool);
+ apr_thread_
+ st->cache_
+ st->cache_
+#else
+ st->lock = NULL;
+ st->cache_
+ st->cache_
+#endif
+
/* This will create a rmm "handler" to get into the shared memory area */
- result = apr_rmm_
+ result = apr_rmm_
if (result != APR_SUCCESS) {
Thanks!