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 /* 20 * This used to be in dyn_load.c. It was extracted into a separate file 21 * to avoid having to link against libdl.{a,so} if the client doesn't call 22 * dlopen. Of course this fails if the collector is in a dynamic 23 * library. -HB 24 */ 25 26 #include "private/gc_priv.h" 27 28 # if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) && !defined(GC_WIN32_PTHREADS)\ 29 || defined(GC_SOLARIS_THREADS) 30 31 # if defined(dlopen) && !defined(GC_USE_LD_WRAP) 32 /* To support various threads pkgs, gc.h interposes on dlopen by */ 33 /* defining "dlopen" to be "GC_dlopen", which is implemented below. */ 34 /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */ 35 /* real system dlopen() in their implementation. We first remove */ 36 /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */ 37 # undef dlopen 38 # endif 39 40 /* Make sure we're not in the middle of a collection, and make */ 41 /* sure we don't start any. Returns previous value of GC_dont_gc. */ 42 /* This is invoked prior to a dlopen call to avoid synchronization */ 43 /* issues. We can't just acquire the allocation lock, since startup */ 44 /* code in dlopen may try to allocate. */ 45 /* This solution risks heap growth in the presence of many dlopen */ 46 /* calls in either a multithreaded environment, or if the library */ 47 /* initialization code allocates substantial amounts of GC'ed memory. */ 48 /* But I don't know of a better solution. */ disable_gc_for_dlopen()49 static void disable_gc_for_dlopen() 50 { 51 LOCK(); 52 while (GC_incremental && GC_collection_in_progress()) { 53 GC_collect_a_little_inner(1000); 54 } 55 ++GC_dont_gc; 56 UNLOCK(); 57 } 58 59 /* Redefine dlopen to guarantee mutual exclusion with */ 60 /* GC_register_dynamic_libraries. */ 61 /* Should probably happen for other operating systems, too. */ 62 63 #include <dlfcn.h> 64 65 #ifdef GC_USE_LD_WRAP __wrap_dlopen(const char * path,int mode)66 void * __wrap_dlopen(const char *path, int mode) 67 #else 68 void * GC_dlopen(const char *path, int mode) 69 #endif 70 { 71 void * result; 72 73 # ifndef USE_PROC_FOR_LIBRARIES 74 disable_gc_for_dlopen(); 75 # endif 76 # ifdef GC_USE_LD_WRAP 77 result = (void *)__real_dlopen(path, mode); 78 # else 79 result = dlopen(path, mode); 80 # endif 81 # ifndef USE_PROC_FOR_LIBRARIES 82 GC_enable(); /* undoes disable_gc_for_dlopen */ 83 # endif 84 return(result); 85 } 86 # endif /* GC_PTHREADS || GC_SOLARIS_THREADS ... */ 87 88 89 90