Back to index

plt-scheme  4.2.1
gc_dlopen.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
00003  * Copyright (c) 1997 by Silicon Graphics.  All rights reserved.
00004  * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
00005  *
00006  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00007  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00008  *
00009  * Permission is hereby granted to use or copy this program
00010  * for any purpose,  provided the above notices are retained on all copies.
00011  * Permission to modify the code and to distribute modified code is granted,
00012  * provided the above notices are retained, and a notice that the code was
00013  * modified is included with the above copyright notice.
00014  *
00015  * Original author: Bill Janssen
00016  * Heavily modified by Hans Boehm and others
00017  */
00018 
00019 /*
00020  * This used to be in dyn_load.c.  It was extracted into a separate file
00021  * to avoid having to link against libdl.{a,so} if the client doesn't call
00022  * dlopen.  Of course this fails if the collector is in a dynamic
00023  * library. -HB
00024  */
00025 
00026 #include "private/gc_priv.h"
00027 
00028 # if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
00029       || defined(GC_SOLARIS_THREADS)
00030 
00031 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
00032     /* To support various threads pkgs, gc.h interposes on dlopen by     */
00033     /* defining "dlopen" to be "GC_dlopen", which is implemented below.  */
00034     /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the   */
00035     /* real system dlopen() in their implementation. We first remove     */
00036     /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
00037 #   undef dlopen
00038 # endif
00039 
00040   /* Make sure we're not in the middle of a collection, and make      */
00041   /* sure we don't start any.      Returns previous value of GC_dont_gc.     */
00042   /* This is invoked prior to a dlopen call to avoid synchronization  */
00043   /* issues.  We can't just acquire the allocation lock, since startup       */
00044   /* code in dlopen may try to allocate.                       */
00045   /* This solution risks heap growth in the presence of many dlopen   */
00046   /* calls in either a multithreaded environment, or if the library   */
00047   /* initialization code allocates substantial amounts of GC'ed memory.      */
00048   /* But I don't know of a better solution.                           */
00049   static void disable_gc_for_dlopen()
00050   {
00051     LOCK();
00052     while (GC_incremental && GC_collection_in_progress()) {
00053        GC_collect_a_little_inner(1000);
00054     }
00055     ++GC_dont_gc;
00056     UNLOCK();
00057   }
00058 
00059   /* Redefine dlopen to guarantee mutual exclusion with */
00060   /* GC_register_dynamic_libraries.                     */
00061   /* Should probably happen for other operating  systems, too. */
00062 
00063 #include <dlfcn.h>
00064 
00065 #ifdef GC_USE_LD_WRAP
00066   void * __wrap_dlopen(const char *path, int mode)
00067 #else
00068   void * GC_dlopen(path, mode)
00069   GC_CONST char * path;
00070   int mode;
00071 #endif
00072 {
00073     void * result;
00074     
00075 #   ifndef USE_PROC_FOR_LIBRARIES
00076       disable_gc_for_dlopen();
00077 #   endif
00078 #   ifdef GC_USE_LD_WRAP
00079       result = (void *)__real_dlopen(path, mode);
00080 #   else
00081       result = dlopen(path, mode);
00082 #   endif
00083 #   ifndef USE_PROC_FOR_LIBRARIES
00084       GC_enable(); /* undoes disable_gc_for_dlopen */
00085 #   endif
00086     return(result);
00087 }
00088 # endif  /* GC_PTHREADS || GC_SOLARIS_THREADS ... */
00089 
00090 
00091