[PATCH] newlib: Unlock the mutex while calling atexit()'ed functions
Takashi Yano <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
The atexit()'ed function may deadlock if it waits for another thread which calls atexit() in the current __call_atexit.c code. This patch unlock __atexit_recursive_mutex while calling atexit()'ed functions to avoid the deadlock mentioned above. glibc and Darwin do the same, so it sounds reasonable. Addresses: https://cygwin.com/pipermail/cygwin/2025-October/258930.html Reported-by: Tomohiro Kashiwada <[email protected]> Reviewed-by: Signed-off-by: Takashi Yano <[email protected]> --- newlib/libc/stdlib/__call_atexit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/newlib/libc/stdlib/__call_atexit.c b/newlib/libc/stdlib/__call_atexit.c index 710440389..44f1f6acc 100644 --- a/newlib/libc/stdlib/__call_atexit.c +++ b/newlib/libc/stdlib/__call_atexit.c @@ -114,6 +114,11 @@ __call_exitprocs (int code, void *d) ind = p->_ind; +#ifndef __SINGLE_THREAD__ + /* Unlock __atexit_recursive_mutex; otherwise, the function fn() may + deadlock if it waits for another thread which calls atexit(). */ + __lock_release_recursive(__atexit_recursive_mutex); +#endif /* Call the function. */ if (!args || (args->_fntypes & i) == 0) fn (); @@ -121,6 +126,9 @@ __call_exitprocs (int code, void *d) (*((void (*)(int, void *)) fn))(code, args->_fnargs[n]); else (*((void (*)(void *)) fn))(args->_fnargs[n]); +#ifndef __SINGLE_THREAD__ + __lock_acquire_recursive(__atexit_recursive_mutex); +#endif /* The function we called call atexit and registered another function (or functions). Call these new functions before -- 2.51.0