summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--doc/README.macros3
-rw-r--r--include/gc.h9
-rw-r--r--win32_threads.c13
4 files changed, 26 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 4142c046..888d0a7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -325,6 +325,10 @@ case "$THREADS" in
AC_DEFINE(THREAD_LOCAL_ALLOC)
fi
fi
+ if test "${enable_win32_dllmain}" = yes; then
+ AC_DEFINE(GC_INSIDE_DLL, 1,
+ [Enable Win32 DllMain-based approach of threads registering.])
+ fi
win32_threads=true
AC_DEFINE([EMPTY_GETENV_RESULTS], [1],
[Wine getenv may not return NULL for missing entry.])
diff --git a/doc/README.macros b/doc/README.macros
index 42bc5059..09a05fca 100644
--- a/doc/README.macros
+++ b/doc/README.macros
@@ -466,6 +466,9 @@ DARWIN_DONT_PARSE_STACK Causes the Darwin port to discover thread
GC_NO_THREADS_DISCOVERY (Darwin and Win32+DLL only) Exclude DllMain-based
(on Windows) and task-threads-based (on Darwin) thread registration support.
+GC_INSIDE_DLL (Win32 only) Enable DllMain-based approach of threads
+ registering even in case GC_DLL is not defined.
+
GC_DISCOVER_TASK_THREADS (Darwin and Win32+DLL only) Compile the collector
with the implicitly turned on task-threads-based (on Darwin) or
DllMain-based (on Windows) approach of threads registering. Only for
diff --git a/include/gc.h b/include/gc.h
index a6eac699..54a9facc 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -1315,6 +1315,15 @@ GC_API void GC_CALL GC_register_has_static_roots_callback(
# define GC_ExitThread _GC_ExitThread
# endif
+# ifdef GC_INSIDE_DLL
+ /* Export GC DllMain to be invoked from client DllMain. */
+# ifdef GC_UNDERSCORE_STDCALL
+# define GC_DllMain _GC_DllMain
+# endif
+ GC_API BOOL WINAPI GC_DllMain(HINSTANCE /* inst */, ULONG /* reason */,
+ LPVOID /* reserved */);
+# endif /* GC_INSIDE_DLL */
+
/* All threads must be created using GC_CreateThread or */
/* GC_beginthreadex, or must explicitly call GC_register_my_thread */
/* (and call GC_unregister_my_thread before thread termination), so */
diff --git a/win32_threads.c b/win32_threads.c
index 859db67c..ae96b3c4 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -78,7 +78,8 @@
/* DllMain-based thread registration is currently incompatible */
/* with thread-local allocation, pthreads and WinCE. */
-#if defined(GC_DLL) && !defined(GC_NO_THREADS_DISCOVERY) && !defined(MSWINCE) \
+#if (defined(GC_DLL) || defined(GC_INSIDE_DLL)) \
+ && !defined(GC_NO_THREADS_DISCOVERY) && !defined(MSWINCE) \
&& !defined(THREAD_LOCAL_ALLOC) && !defined(GC_PTHREADS)
# include "atomic_ops.h"
@@ -2569,8 +2570,14 @@ GC_INNER void GC_thr_init(void)
/* collector. (The alternative of initializing the collector here */
/* seems dangerous, since DllMain is limited in what it can do.) */
- BOOL WINAPI DllMain(HINSTANCE inst GC_ATTR_UNUSED, ULONG reason,
- LPVOID reserved GC_ATTR_UNUSED)
+# ifdef GC_INSIDE_DLL
+ /* Export only if needed by client. */
+ GC_API
+# else
+# define GC_DllMain DllMain
+# endif
+ BOOL WINAPI GC_DllMain(HINSTANCE inst GC_ATTR_UNUSED, ULONG reason,
+ LPVOID reserved GC_ATTR_UNUSED)
{
struct GC_stack_base sb;
DWORD thread_id;