Mercurial > emacs
diff gc/gc_dlopen.c @ 51488:5de98dce4bd1
*** empty log message ***
author | Dave Love <fx@gnu.org> |
---|---|
date | Thu, 05 Jun 2003 17:49:22 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gc/gc_dlopen.c Thu Jun 05 17:49:22 2003 +0000 @@ -0,0 +1,91 @@ +/* + * 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 "private/gc_priv.h" + +# if (defined(GC_PTHREADS) && !defined(GC_MACOSX_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 ... */ + + +