]> granicus.if.org Git - gc/commitdiff
Win32: allow DllMain chaining on the client side
authorIvan Maidanski <ivmai@mail.ru>
Tue, 10 Jan 2012 06:27:33 +0000 (10:27 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 10 Jan 2012 06:27:33 +0000 (10:27 +0400)
(Reworked commits e55eb9c34a996f 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.

configure.ac
doc/README.macros
include/gc.h
win32_threads.c

index 4142c0463a33497e922ea500f806671f8bd5c4d5..888d0a7fa824858e58d75a4380a4f7dfead8b760 100644 (file)
@@ -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.])
index 42bc50594031d69488c4cfe23fdf791668a66355..09a05fcafa31a5804b6905e959f34f796c3f6e9e 100644 (file)
@@ -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
index a6eac699ec7aa55d25a9a46504d8d21b0c15ef7d..54a9facc2ee30e03baa6dca5636a295dfa5d1daa 100644 (file)
@@ -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 */
index 859db67cac45b79308433674e1daba65d5b241ab..ae96b3c49f97235a4fa4323673f1df044496e39b 100644 (file)
@@ -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;