From: Ivan Maidanski Date: Tue, 10 Jan 2012 06:27:33 +0000 (+0400) Subject: Win32: allow DllMain chaining on the client side X-Git-Tag: gc7_3alpha2~238 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7358d20b30a4154f7cd31d33e6fd339526211d4;p=gc 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. --- 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;