Import boehm-gc snapshot, taken from
[official-gcc.git] / boehm-gc / gc_dlopen.c
blob0da82278600480c90f0d3d607909fab1543f86dc
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.
6 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
16 #include "private/gc_priv.h"
18 /* This used to be in dyn_load.c. It was extracted into a separate */
19 /* file to avoid having to link against libdl.{a,so} if the client */
20 /* doesn't call dlopen. Of course this fails if the collector is in */
21 /* a dynamic library. -HB */
22 #if defined(GC_PTHREADS) && !defined(GC_NO_DLOPEN)
24 #undef GC_MUST_RESTORE_REDEFINED_DLOPEN
25 #if defined(dlopen) && !defined(GC_USE_LD_WRAP)
26 /* To support various threads pkgs, gc.h interposes on dlopen by */
27 /* defining "dlopen" to be "GC_dlopen", which is implemented below. */
28 /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */
29 /* real system dlopen() in their implementation. We first remove */
30 /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
31 # undef dlopen
32 # define GC_MUST_RESTORE_REDEFINED_DLOPEN
33 #endif
35 /* Make sure we're not in the middle of a collection, and make sure we */
36 /* don't start any. This is invoked prior to a dlopen call to avoid */
37 /* synchronization issues. We can't just acquire the allocation lock, */
38 /* since startup code in dlopen may try to allocate. This solution */
39 /* risks heap growth (or, even, heap overflow) in the presence of many */
40 /* dlopen calls in either a multi-threaded environment, or if the */
41 /* library initialization code allocates substantial amounts of GC'ed */
42 /* memory. */
43 #ifndef USE_PROC_FOR_LIBRARIES
44 static void disable_gc_for_dlopen(void)
46 DCL_LOCK_STATE;
47 LOCK();
48 while (GC_incremental && GC_collection_in_progress()) {
49 GC_collect_a_little_inner(1000);
51 ++GC_dont_gc;
52 UNLOCK();
54 #endif
56 /* Redefine dlopen to guarantee mutual exclusion with */
57 /* GC_register_dynamic_libraries. Should probably happen for */
58 /* other operating systems, too. */
60 /* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */
61 #ifdef GC_USE_LD_WRAP
62 # define WRAP_DLFUNC(f) __wrap_##f
63 # define REAL_DLFUNC(f) __real_##f
64 void * REAL_DLFUNC(dlopen)(const char *, int);
65 #else
66 # define WRAP_DLFUNC(f) GC_##f
67 # define REAL_DLFUNC(f) f
68 #endif
70 GC_API void * WRAP_DLFUNC(dlopen)(const char *path, int mode)
72 void * result;
74 # ifndef USE_PROC_FOR_LIBRARIES
75 /* Disable collections. This solution risks heap growth (or, */
76 /* even, heap overflow) but there seems no better solutions. */
77 disable_gc_for_dlopen();
78 # endif
79 result = REAL_DLFUNC(dlopen)(path, mode);
80 # ifndef USE_PROC_FOR_LIBRARIES
81 GC_enable(); /* undoes disable_gc_for_dlopen */
82 # endif
83 return(result);
86 #ifdef GC_USE_LD_WRAP
87 /* Define GC_ function as an alias for the plain one, which will be */
88 /* intercepted. This allows files which include gc.h, and hence */
89 /* generate references to the GC_ symbol, to see the right symbol. */
90 GC_API void *GC_dlopen(const char *path, int mode)
92 return dlopen(path, mode);
94 #endif /* GC_USE_LD_WRAP */
96 #ifdef GC_MUST_RESTORE_REDEFINED_DLOPEN
97 # define dlopen GC_dlopen
98 #endif
100 #endif /* GC_PTHREADS && !GC_NO_DLOPEN */