Skip to content

Commit 5bb94d9

Browse files
committed
metrics: avoid double-free crash on shutdown by not calling pthread_exit
fixes #1207; thanks @studersi upon exit, do write cached metrics into shared memory before exiting Signed-off-by: Hans Zandbelt <[email protected]>
1 parent 5ab1ce7 commit 5bb94d9

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

ChangeLog

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
03/18/2025
2-
- use case insensitive hostname/domain comparison in oidc_check_cookie_domain
3-
- remove the Location header from HTML based step up authentication redirects
2+
- core: use case insensitive hostname/domain comparison in oidc_check_cookie_domain
3+
- authz: remove the Location header from HTML based step up authentication redirects
44
as it may conflict with its HTTP 200 status code and confuse middle boxes
5+
- metrics: avoid double-free on shutdown by not calling pthread_exit; fixes #1207; thanks @studersi
6+
- metrics: upon exit, do write cached metrics into shared memory before exiting
57
- bump to 2.4.16.9dev
68

79
02/17/2025

src/metrics.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,8 @@ static unsigned int oidc_metric_random_int(unsigned int mod) {
725725
return v % mod;
726726
}
727727

728+
#define OIDC_METRICS_POLL_INTERVAL 250
729+
728730
/*
729731
* thread that periodically writes the local data into the shared memory
730732
*/
@@ -734,14 +736,21 @@ static void *APR_THREAD_FUNC oidc_metrics_thread_run(apr_thread_t *thread, void
734736
/* sleep for a short random time <1s so child processes write-lock on a different frequency */
735737
apr_sleep(apr_time_from_msec(oidc_metric_random_int(1000)));
736738

739+
/* calculate the number of short sleep intervals */
740+
int n = _oidc_metrics_interval(s) / apr_time_from_msec(OIDC_METRICS_POLL_INTERVAL);
741+
737742
/* see if we are asked to exit */
738743
while (_oidc_metrics_thread_exit == FALSE) {
739744

740-
apr_sleep(_oidc_metrics_interval(s));
745+
/* break up the sleep interval in short intervals so we can exit timely fashion without confusing Apache
746+
* at shutdown */
747+
for (int i = 0; i < n; i++) {
748+
apr_sleep(apr_time_from_msec(OIDC_METRICS_POLL_INTERVAL));
749+
if (_oidc_metrics_thread_exit == TRUE)
750+
break;
751+
}
741752

742-
// NB: exit here because the parent thread may have cleaned up the shared memory segment
743-
if (_oidc_metrics_thread_exit == TRUE)
744-
break;
753+
// NB: no exit here because we need to write our local metrics into the cache before exiting
745754

746755
/* lock the mutex that protects the locally cached metrics */
747756
oidc_cache_mutex_lock(s->process->pool, s, _oidc_metrics_process_mutex);
@@ -757,7 +766,8 @@ static void *APR_THREAD_FUNC oidc_metrics_thread_run(apr_thread_t *thread, void
757766
oidc_cache_mutex_unlock(s->process->pool, s, _oidc_metrics_process_mutex);
758767
}
759768

760-
apr_thread_exit(thread, APR_SUCCESS);
769+
/* NB: don't call apr_thread_exit here because it seems that Apache is cleaning up its own threads */
770+
// apr_thread_exit(thread, APR_SUCCESS);
761771

762772
return NULL;
763773
}

0 commit comments

Comments
 (0)