Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / gc_dlopen.c
index d0a26e164cbdee8cd5b31b3ab363904cac24f44f..3e0b1a39378ac5afda6fa2659b68e0a29be5c8c2 100644 (file)
@@ -16,6 +16,8 @@
  * Heavily modified by Hans Boehm and others
  */
 
+#include "private/gc_priv.h"
+
 /*
  * This used to be in dyn_load.c.  It was extracted into a separate file
  * to avoid having to link against libdl.{a,so} if the client doesn't call
  * library. -HB
  */
 
-#include "private/gc_priv.h"
-
-# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) && !defined(GC_WIN32_PTHREADS)\
-      || defined(GC_SOLARIS_THREADS)
+# if defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS) \
+     && !defined(GC_WIN32_PTHREADS)
 
+# undef GC_MUST_RESTORE_REDEFINED_DLOPEN
 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
     /* To support various threads pkgs, gc.h interposes on dlopen by     */
     /* defining "dlopen" to be "GC_dlopen", which is implemented below.  */
     /* real system dlopen() in their implementation. We first remove     */
     /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
 #   undef dlopen
+#   define GC_MUST_RESTORE_REDEFINED_DLOPEN
 # endif
 
-  GC_bool GC_collection_in_progress(void);
-
-  /* Make sure we're not in the middle of a collection, and make       */
-  /* sure we don't start any.  Returns previous value of GC_dont_gc.   */
-  /* This is invoked prior to a dlopen call to avoid synchronization   */
-  /* issues.  We can't just acquire the allocation lock, since startup         */
-  /* code in dlopen may try to allocate.                               */
-  /* This solution risks heap growth in the presence of many dlopen    */
-  /* calls in either a multithreaded environment, or if the library    */
-  /* initialization code allocates substantial amounts of GC'ed memory.        */
-  /* But I don't know of a better solution.                            */
+  /* Make sure we're not in the middle of a collection, and make        */
+  /* sure we don't start any.   Returns previous value of GC_dont_gc.   */
+  /* This is invoked prior to a dlopen call to avoid synchronization    */
+  /* issues.  We can't just acquire the allocation lock, since startup  */
+  /* code in dlopen may try to allocate.                                */
+  /* This solution risks heap growth in the presence of many dlopen     */
+  /* calls in either a multithreaded environment, or if the library     */
+  /* initialization code allocates substantial amounts of GC'ed memory. */
+  /* But I don't know of a better solution.                             */
   static void disable_gc_for_dlopen(void)
   {
     LOCK();
     while (GC_incremental && GC_collection_in_progress()) {
-       GC_collect_a_little_inner(1000);
+        GC_collect_a_little_inner(1000);
     }
     ++GC_dont_gc;
     UNLOCK();
   }
 
-  /* Redefine dlopen to guarantee mutual exclusion with        */
-  /* GC_register_dynamic_libraries.                    */
-  /* Should probably happen for other operating        systems, too. */
+  /* Redefine dlopen to guarantee mutual exclusion with */
+  /* GC_register_dynamic_libraries.                     */
+  /* Should probably happen for other operating systems, too. */
 
 #include <dlfcn.h>
 
+/* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */
 #ifdef GC_USE_LD_WRAP
-  void * __wrap_dlopen(const char *path, int mode)
+#   define WRAP_DLFUNC(f) __wrap_##f
+#   define REAL_DLFUNC(f) __real_##f
 #else
-  void * GC_dlopen(const char *path, int mode)
+#   define WRAP_DLFUNC(f) GC_##f
+#   define REAL_DLFUNC(f) f
 #endif
+
+GC_API void * WRAP_DLFUNC(dlopen)(const char *path, int mode)
 {
     void * result;
-    
+
 #   ifndef USE_PROC_FOR_LIBRARIES
       disable_gc_for_dlopen();
 #   endif
-#   ifdef GC_USE_LD_WRAP
-      result = (void *)__real_dlopen(path, mode);
-#   else
-      result = dlopen(path, mode);
-#   endif
+    result = (void *)REAL_DLFUNC(dlopen)(path, mode);
 #   ifndef USE_PROC_FOR_LIBRARIES
       GC_enable(); /* undoes disable_gc_for_dlopen */
 #   endif
     return(result);
 }
-# endif  /* GC_PTHREADS || GC_SOLARIS_THREADS ... */
 
+#ifdef GC_USE_LD_WRAP
+  /* Define GC_ function as an alias for the plain one, which will be   */
+  /* intercepted.  This allows files which include gc.h, and hence      */
+  /* generate references to the GC_ symbol, to see the right symbol.    */
+  GC_API int GC_dlopen(const char *path, int mode)
+  {
+    return dlopen(path, mode);
+  }
+#endif /* Linker-based interception. */
 
+# ifdef GC_MUST_RESTORE_REDEFINED_DLOPEN
+#   define dlopen GC_dlopen
+# endif
 
+#endif  /* GC_PTHREADS */