diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2012-01-10 10:27:33 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2012-01-10 10:27:33 +0400 |
commit | e7358d20b30a4154f7cd31d33e6fd339526211d4 (patch) | |
tree | af1d03c32d6e996887525f6b31d06efaf1ceab5c | |
parent | 03a174fbb1f5718fd5fadba1a989b17464032d4d (diff) | |
download | bdwgc-e7358d20b30a4154f7cd31d33e6fd339526211d4.tar.gz |
Win32: allow DllMain chaining on the client side
(Reworked commits e55eb9c, 34a996f from 'mono_libgc' branch)
* configure.ac (enable_win32_dllmain): Recognize new AC "enable"
option.
* configure.ac (GC_INSIDE_DLL): New AC macro (defined only if
enable_win32_dllmain).
* README.macros (GC_INSIDE_DLL): Document.
* include/gc.h (GC_DllMain): Declare as API function (for Win32) if
GC_INSIDE_DLL.
* win32_threads.c (GC_INSIDE_DLL): Recognize (treat the same as
GC_DLL).
* win32_threads.c (DllMain): Rename to GC_DllMain; use GC_API export
declarator if GC_INSIDE_DLL, otherwise define GC_DllMain macro as
a synonym to DllMain.
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | doc/README.macros | 3 | ||||
-rw-r--r-- | include/gc.h | 9 | ||||
-rw-r--r-- | win32_threads.c | 13 |
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; |