96 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * 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(GC_PTHREADS) || 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.				*/
 | 
						|
  /* 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  /* GC_PTHREADS || GC_SOLARIS_THREADS ... */
 | 
						|
 | 
						|
 | 
						|
 |