According to docs, the order is unspecified, but running them in
reverse order would be more logical.

When libstdc++ is built, it can either provide its own implementation
of __cxa_thread_atexit or use one from the host environment.

When libstdc++ is cross compiled, the configure script doesn't do any
linking tests and doesn't detect the mingw-w64-crt implementation of
__cxa_thread_atexit, and always provides its own implementation
instead.

When the libstdc++/libsupc++ implementation of __cxa_thread_atexit is
used in conjunction with emulated TLS, both emutls and libsupc++
register destructors to be executed via pthread_key_create; one for
freeing the per-thread memory allocated for the TLS objects, and
one for executing the destructors. They are registered in a sequential
order; first emutls registers the destructor for freeing the memory,
followed by libsupc++ registers a destructor for running the TLS
object destructors.

Therefore, running the pthread key destructors in reverse order makes
sure that the TLS object destructors are called (via libsupc++) before
their memory is deallocated (via emutls).

This pattern also matches how destructors normally are executed - in
opposite order compared with how they were constructors.
---
This part of the fix should at least work the same regardless of
whether winpthreads is in a separate DLL or statically linked into
the end user executable.
---
 mingw-w64-libraries/winpthreads/src/thread.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mingw-w64-libraries/winpthreads/src/thread.c 
b/mingw-w64-libraries/winpthreads/src/thread.c
index 3535797e3..247cc2297 100644
--- a/mingw-w64-libraries/winpthreads/src/thread.c
+++ b/mingw-w64-libraries/winpthreads/src/thread.c
@@ -971,7 +971,8 @@ void
 _pthread_cleanup_dest (pthread_t t)
 {
        _pthread_v *tv;
-       unsigned int i, j;
+       unsigned int j;
+       int i;
 
        if (!t)
                return;
@@ -984,7 +985,7 @@ _pthread_cleanup_dest (pthread_t t)
                int flag = 0;
 
                pthread_spin_lock (&tv->spin_keys);
-               for (i = 0; i < tv->keymax; i++)
+               for (i = tv->keymax - 1; i >= 0; i--)
                {
                        void *val = tv->keyval[i];
 
-- 
2.43.0



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to