Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / gc_dlopen.c
1 /*
2  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
3  * Copyright (c) 1997 by Silicon Graphics.  All rights reserved.
4  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
5  *
6  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
8  *
9  * Permission is hereby granted to use or copy this program
10  * for any purpose,  provided the above notices are retained on all copies.
11  * Permission to modify the code and to distribute modified code is granted,
12  * provided the above notices are retained, and a notice that the code was
13  * modified is included with the above copyright notice.
14  *
15  * Original author: Bill Janssen
16  * Heavily modified by Hans Boehm and others
17  */
18
19 #include "private/gc_priv.h"
20
21 /*
22  * This used to be in dyn_load.c.  It was extracted into a separate file
23  * to avoid having to link against libdl.{a,so} if the client doesn't call
24  * dlopen.  Of course this fails if the collector is in a dynamic
25  * library. -HB
26  */
27
28 # if defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS) \
29      && !defined(GC_WIN32_PTHREADS)
30
31 # undef GC_MUST_RESTORE_REDEFINED_DLOPEN
32 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
33     /* To support various threads pkgs, gc.h interposes on dlopen by     */
34     /* defining "dlopen" to be "GC_dlopen", which is implemented below.  */
35     /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the   */
36     /* real system dlopen() in their implementation. We first remove     */
37     /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
38 #   undef dlopen
39 #   define GC_MUST_RESTORE_REDEFINED_DLOPEN
40 # endif
41
42   /* Make sure we're not in the middle of a collection, and make        */
43   /* sure we don't start any.   Returns previous value of GC_dont_gc.   */
44   /* This is invoked prior to a dlopen call to avoid synchronization    */
45   /* issues.  We can't just acquire the allocation lock, since startup  */
46   /* code in dlopen may try to allocate.                                */
47   /* This solution risks heap growth in the presence of many dlopen     */
48   /* calls in either a multithreaded environment, or if the library     */
49   /* initialization code allocates substantial amounts of GC'ed memory. */
50   /* But I don't know of a better solution.                             */
51   static void disable_gc_for_dlopen(void)
52   {
53     LOCK();
54     while (GC_incremental && GC_collection_in_progress()) {
55         GC_collect_a_little_inner(1000);
56     }
57     ++GC_dont_gc;
58     UNLOCK();
59   }
60
61   /* Redefine dlopen to guarantee mutual exclusion with */
62   /* GC_register_dynamic_libraries.                     */
63   /* Should probably happen for other operating systems, too. */
64
65 #include <dlfcn.h>
66
67 /* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */
68 #ifdef GC_USE_LD_WRAP
69 #   define WRAP_DLFUNC(f) __wrap_##f
70 #   define REAL_DLFUNC(f) __real_##f
71 #else
72 #   define WRAP_DLFUNC(f) GC_##f
73 #   define REAL_DLFUNC(f) f
74 #endif
75
76 GC_API void * WRAP_DLFUNC(dlopen)(const char *path, int mode)
77 {
78     void * result;
79
80 #   ifndef USE_PROC_FOR_LIBRARIES
81       disable_gc_for_dlopen();
82 #   endif
83     result = (void *)REAL_DLFUNC(dlopen)(path, mode);
84 #   ifndef USE_PROC_FOR_LIBRARIES
85       GC_enable(); /* undoes disable_gc_for_dlopen */
86 #   endif
87     return(result);
88 }
89
90 #ifdef GC_USE_LD_WRAP
91   /* Define GC_ function as an alias for the plain one, which will be   */
92   /* intercepted.  This allows files which include gc.h, and hence      */
93   /* generate references to the GC_ symbol, to see the right symbol.    */
94   GC_API int GC_dlopen(const char *path, int mode)
95   {
96     return dlopen(path, mode);
97   }
98 #endif /* Linker-based interception. */
99
100 # ifdef GC_MUST_RESTORE_REDEFINED_DLOPEN
101 #   define dlopen GC_dlopen
102 # endif
103
104 #endif  /* GC_PTHREADS */