Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-03 Thread Liu Hao
在 2018/8/3 18:36, Martin Storsjö 写道:
> Are you sure that you installed the latest set of headers as well? I 
> added this new typedef and a function declaration in one of the patches.
> 
> // Martin

.. you are right, On my system a header is installed into 
'/mingw64/include/process.h' unintentionally, which overrides 
'/mingw64/x86_64-w64-mingw32/include/process.h'. I have no idea where it 
came from. I will try deleting my local directories and reinstalling all 
packages.

-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-03 Thread Martin Storsjö

On Fri, 3 Aug 2018, Liu Hao wrote:


在 2018/8/3 4:18, Martin Storsjö 写道:

Renamed the typedef to dtor_fn


These 4 patches look good to me.


Thanks for the thorough review! Pushed.



Compiling with GCC 8.2 now fails with this error:

```
E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/misc/register_tls_atexit.c:12:8: 
error: unknown type name '_tls_callback_type'

static _tls_callback_type callback;
   ^~
```


Are you sure that you installed the latest set of headers as well? I added 
this new typedef and a function declaration in one of the patches.


// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-03 Thread Liu Hao
在 2018/8/3 4:18, Martin Storsjö 写道:
> Renamed the typedef to dtor_fn
> 
>> These 4 patches look good to me.
> 
> Thanks for the thorough review! Pushed.
> 
>
Compiling with GCC 8.2 now fails with this error:

```
E:/GitHub/MINGW-packages/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/misc/register_tls_atexit.c:12:8:
 
error: unknown type name '_tls_callback_type'
  static _tls_callback_type callback;
 ^~
```

-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö

On Thu, 2 Aug 2018, Liu Hao wrote:


在 2018/8/2 19:22, Martin Storsjö 写道:

+
+typedef void (__thiscall * dtor)(void*);
+int __cxa_atexit(dtor dtor, void *obj, void *dso);
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
+
+typedef struct dtor_obj dtor_obj;
+struct dtor_obj {
+  dtor dtor;


It is a bit strange to see the same identifier be repeated here. I 
suggest you rename the typedef to `dtor_fn` or `dtor_proc`.


Renamed the typedef to dtor_fn


These 4 patches look good to me.


Thanks for the thorough review! Pushed.

// Martin
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


Re: [Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Liu Hao
在 2018/8/2 19:22, Martin Storsjö 写道:
> +
> +typedef void (__thiscall * dtor)(void*);
> +int __cxa_atexit(dtor dtor, void *obj, void *dso);
> +int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
> +
> +typedef struct dtor_obj dtor_obj;
> +struct dtor_obj {
> +  dtor dtor;

It is a bit strange to see the same identifier be repeated here. I 
suggest you rename the typedef to `dtor_fn` or `dtor_proc`.

These 4 patches look good to me.

-- 
Best regards,
LH_Mouse
--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


[Mingw-w64-public] [PATCHv2 1/4] crt: Add an implementation of __cxa_atexit and __cxa_thread_atexit

2018-08-02 Thread Martin Storsjö
In order to properly call destructors of a DLL when that DLL is
unloaded, we need to provide these as part of the static library
libmingw32.a, which gets linked into the module itself.

C++ libraries (both libstdc++ and libcxxabi) can also provide the
function __cxa_thread_atexit, and defer the actual handling to the
platform via a __cxa_thread_atexit_impl function. However, if linking
a C++ standard library dynamically, that would mean that all destructors
are registered in the C++ DLL and only invoked when that one is unloaded,
not when an individual DLL gets unloaded.

Therefore we need to provide these functions directly in a static library
that gets linked into each module (if referenced).

This probably doesn't end up used with GCC and libstdc++ (which still
probably provides its own __cxa_thread_atexit which will be linked before
libmingw32.a). But it does work with clang (if compiling with
-fuse-cxa-atexit) and libcxxabi (which doesn't provide any
__cxa_thread_atexit when targeting mingw).

Signed-off-by: Martin Storsjö 
---
Removed code for cleaning up other threads' pending destructors, added
a verbose comment about the matter.
---
 mingw-w64-crt/Makefile.am  |   2 +-
 mingw-w64-crt/crt/cxa_atexit.c | 113 +
 2 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 mingw-w64-crt/crt/cxa_atexit.c

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 8ca1072..d98fa3a 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -119,7 +119,7 @@ src_libmingw32=include/oscalls.h include/internal.h 
include/sect_attribs.h \
   crt/mingw_custom.c  crt/mingw_helpers.c  \
   crt/pseudo-reloc.c  crt/udll_argv.c  \
   crt/xtxtmode.c  crt/crt_handler.c\
-  crt/tlsthrd.c   crt/tlsmthread.c crt/tlsmcrt.c
+  crt/tlsthrd.c   crt/tlsmthread.c crt/tlsmcrt.c   crt/cxa_atexit.c
 
 src_libscrnsave=libsrc/scrnsave.c
 src_libscrnsavw=libsrc/scrnsave.c
diff --git a/mingw-w64-crt/crt/cxa_atexit.c b/mingw-w64-crt/crt/cxa_atexit.c
new file mode 100644
index 000..d74968d
--- /dev/null
+++ b/mingw-w64-crt/crt/cxa_atexit.c
@@ -0,0 +1,113 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+
+#include 
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include 
+
+#include 
+#include 
+#include 
+
+
+typedef void (__thiscall * dtor)(void*);
+int __cxa_atexit(dtor dtor, void *obj, void *dso);
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso);
+
+typedef struct dtor_obj dtor_obj;
+struct dtor_obj {
+  dtor dtor;
+  void *obj;
+  dtor_obj *next;
+};
+
+HANDLE __dso_handle;
+
+static CRITICAL_SECTION lock;
+static int inited = 0;
+static dtor_obj *global_dtors = NULL;
+static __thread dtor_obj *tls_dtors = NULL;
+
+int __cxa_atexit(dtor dtor, void *obj, void *dso) {
+  if (!inited)
+return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  EnterCriticalSection();
+  handler->next = global_dtors;
+  global_dtors = handler;
+  LeaveCriticalSection();
+  return 0;
+}
+
+static void run_dtor_list(dtor_obj **ptr) {
+  dtor_obj *list = *ptr;
+  while (list) {
+list->dtor(list->obj);
+dtor_obj *next = list->next;
+free(list);
+list = next;
+  }
+  *ptr = NULL;
+}
+
+int __cxa_thread_atexit(dtor dtor, void *obj, void *dso) {
+  if (!inited)
+return 1;
+  assert(!dso || dso == &__dso_handle);
+  dtor_obj *handler = (dtor_obj *) calloc(1, sizeof(*handler));
+  if (!handler)
+return 1;
+  handler->dtor = dtor;
+  handler->obj = obj;
+  handler->next = tls_dtors;
+  tls_dtors = handler;
+  return 0;
+}
+
+static void WINAPI tls_callback(HANDLE hDllHandle, DWORD dwReason, LPVOID 
__UNUSED_PARAM(lpReserved)) {
+  switch (dwReason) {
+  case DLL_PROCESS_ATTACH:
+if (inited == 0) {
+  InitializeCriticalSection();
+  __dso_handle = hDllHandle;
+}
+inited = 1;
+break;
+  case DLL_PROCESS_DETACH:
+// If there are other threads still running that haven't been detached,
+// we don't attempt to run their destructors (MSVC doesn't either), but
+// simply leak the destructor list and whatever resources the destructors
+// would have released.
+// From Vista onwards, we could have used FlsAlloc to get a TLS key that
+// runs a destructor on each thread that has a value attached ot it, but
+// since MSVC doesn't run destructors on other threads in this case,
+// users shouldn't assume it and we don't attempt to do anything 
potentially
+// risky about it. TL;DR, threads with pending TLS destructors for a DLL
+// need to be joined before unloading the DLL.
+run_dtor_list(_dtors);
+run_dtor_list(_dtors);
+