version 1.1, 2002/07/24 08:00:09 |
version 1.2, 2003/06/24 05:11:32 |
|
|
/* |
/* |
* This used to be in dyn_load.c. It was extracted into a separate file |
* 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 |
* to avoid having to link against libdl.{a,so} if the client doesn't call |
* dlopen. -HB |
* dlopen. Of course this fails if the collector is in a dynamic |
|
* library. -HB |
*/ |
*/ |
|
|
#include "private/gc_priv.h" |
#include "private/gc_priv.h" |
|
|
# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) |
# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \ |
|
|| defined(GC_SOLARIS_THREADS) |
|
|
# if defined(dlopen) && !defined(GC_USE_LD_WRAP) |
# if defined(dlopen) && !defined(GC_USE_LD_WRAP) |
/* To support various threads pkgs, gc.h interposes on dlopen by */ |
/* To support various threads pkgs, gc.h interposes on dlopen by */ |
|
|
/* calls in either a multithreaded environment, or if the library */ |
/* calls in either a multithreaded environment, or if the library */ |
/* initialization code allocates substantial amounts of GC'ed memory. */ |
/* initialization code allocates substantial amounts of GC'ed memory. */ |
/* But I don't know of a better solution. */ |
/* But I don't know of a better solution. */ |
/* This can still deadlock if the client explicitly starts a GC */ |
static void disable_gc_for_dlopen() |
/* during the dlopen. He shouldn't do that. */ |
|
static GC_bool disable_gc_for_dlopen() |
|
{ |
{ |
GC_bool result; |
|
LOCK(); |
LOCK(); |
result = GC_dont_gc; |
|
while (GC_incremental && GC_collection_in_progress()) { |
while (GC_incremental && GC_collection_in_progress()) { |
GC_collect_a_little_inner(1000); |
GC_collect_a_little_inner(1000); |
} |
} |
GC_dont_gc = TRUE; |
++GC_dont_gc; |
UNLOCK(); |
UNLOCK(); |
return(result); |
|
} |
} |
|
|
/* Redefine dlopen to guarantee mutual exclusion with */ |
/* Redefine dlopen to guarantee mutual exclusion with */ |
|
|
#endif |
#endif |
{ |
{ |
void * result; |
void * result; |
GC_bool dont_gc_save; |
|
|
|
# ifndef USE_PROC_FOR_LIBRARIES |
# ifndef USE_PROC_FOR_LIBRARIES |
dont_gc_save = disable_gc_for_dlopen(); |
disable_gc_for_dlopen(); |
# endif |
# endif |
# ifdef GC_USE_LD_WRAP |
# ifdef GC_USE_LD_WRAP |
result = (void *)__real_dlopen(path, mode); |
result = (void *)__real_dlopen(path, mode); |
|
|
result = dlopen(path, mode); |
result = dlopen(path, mode); |
# endif |
# endif |
# ifndef USE_PROC_FOR_LIBRARIES |
# ifndef USE_PROC_FOR_LIBRARIES |
GC_dont_gc = dont_gc_save; |
GC_enable(); /* undoes disable_gc_for_dlopen */ |
# endif |
# endif |
return(result); |
return(result); |
} |
} |