Updates from 0.2.1 into 0.2.1-inu-1.5
This commit is contained in:
		
							
								
								
									
										96
									
								
								gc/gc_dlopen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								gc/gc_dlopen.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* | ||||
|  * 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.  -HB | ||||
|  */ | ||||
|  | ||||
| #include "private/gc_priv.h" | ||||
|  | ||||
| # if defined(LINUX_THREADS) || defined(SOLARIS_THREADS) \ | ||||
|      || defined(HPUX_THREADS) || defined(IRIX_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.				*/ | ||||
|   /* This can still deadlock if the client explicitly starts a GC 	*/ | ||||
|   /* during the dlopen.  He shouldn't do that.				*/ | ||||
|   static GC_bool disable_gc_for_dlopen() | ||||
|   { | ||||
|     GC_bool result; | ||||
|     LOCK(); | ||||
|     result = GC_dont_gc; | ||||
|     while (GC_incremental && GC_collection_in_progress()) { | ||||
| 	GC_collect_a_little_inner(1000); | ||||
|     } | ||||
|     GC_dont_gc = TRUE; | ||||
|     UNLOCK(); | ||||
|     return(result); | ||||
|   } | ||||
|  | ||||
|   /* 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; | ||||
|     GC_bool dont_gc_save; | ||||
|      | ||||
| #   ifndef USE_PROC_FOR_LIBRARIES | ||||
|       dont_gc_save = 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_dont_gc = dont_gc_save; | ||||
| #   endif | ||||
|     return(result); | ||||
| } | ||||
| # endif  /* LINUX_THREADS || SOLARIS_THREADS || ... */ | ||||
|  | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user