* Moved boehm-gc from src/ to src/mm/.
[cacao.git] / src / mm / boehm-gc / gc_dlopen.c
diff --git a/src/mm/boehm-gc/gc_dlopen.c b/src/mm/boehm-gc/gc_dlopen.c
new file mode 100644 (file)
index 0000000..75616b9
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
+ * Copyright (c) 1997 by Silicon Graphics.  All rights reserved.
+ * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose,  provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ *
+ * Original author: Bill Janssen
+ * Heavily modified by Hans Boehm and others
+ */
+
+/*
+ * 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
+ * dlopen.  Of course this fails if the collector is in a dynamic
+ * library. -HB
+ */
+
+#include "config.h"
+
+#include "private/gc_priv.h"
+
+# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
+      || defined(GC_SOLARIS_THREADS)
+
+# 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.  */
+    /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the   */
+    /* real system dlopen() in their implementation. We first remove     */
+    /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
+#   undef dlopen
+# endif
+
+  /* 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()
+  {
+    LOCK();
+    while (GC_incremental && GC_collection_in_progress()) {
+       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. */
+
+#include <dlfcn.h>
+
+#ifdef GC_USE_LD_WRAP
+  void * __wrap_dlopen(const char *path, int mode)
+#else
+  void * GC_dlopen(path, mode)
+  GC_CONST char * path;
+  int mode;
+#endif
+{
+    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
+#   ifndef USE_PROC_FOR_LIBRARIES
+      GC_enable(); /* undoes disable_gc_for_dlopen */
+#   endif
+    return(result);
+}
+# endif  /* GC_PTHREADS || GC_SOLARIS_THREADS ... */
+
+
+