Mercurial > emacs
comparison 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 |
comparison
equal
deleted
inserted
replaced
51487:01d68b199093 | 51488:5de98dce4bd1 |
---|---|
1 /* | |
2 * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. | |
3 * Copyright (c) 1997 by Silicon Graphics. All rights reserved. | |
4 * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. | |
5 * | |
6 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED | |
7 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. | |
8 * | |
9 * Permission is hereby granted to use or copy this program | |
10 * for any purpose, provided the above notices are retained on all copies. | |
11 * Permission to modify the code and to distribute modified code is granted, | |
12 * provided the above notices are retained, and a notice that the code was | |
13 * modified is included with the above copyright notice. | |
14 * | |
15 * Original author: Bill Janssen | |
16 * Heavily modified by Hans Boehm and others | |
17 */ | |
18 | |
19 /* | |
20 * This used to be in dyn_load.c. It was extracted into a separate file | |
21 * to avoid having to link against libdl.{a,so} if the client doesn't call | |
22 * dlopen. Of course this fails if the collector is in a dynamic | |
23 * library. -HB | |
24 */ | |
25 | |
26 #include "private/gc_priv.h" | |
27 | |
28 # if (defined(GC_PTHREADS) && !defined(GC_MACOSX_THREADS)) \ | |
29 || defined(GC_SOLARIS_THREADS) | |
30 | |
31 # if defined(dlopen) && !defined(GC_USE_LD_WRAP) | |
32 /* To support various threads pkgs, gc.h interposes on dlopen by */ | |
33 /* defining "dlopen" to be "GC_dlopen", which is implemented below. */ | |
34 /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */ | |
35 /* real system dlopen() in their implementation. We first remove */ | |
36 /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */ | |
37 # undef dlopen | |
38 # endif | |
39 | |
40 /* Make sure we're not in the middle of a collection, and make */ | |
41 /* sure we don't start any. Returns previous value of GC_dont_gc. */ | |
42 /* This is invoked prior to a dlopen call to avoid synchronization */ | |
43 /* issues. We can't just acquire the allocation lock, since startup */ | |
44 /* code in dlopen may try to allocate. */ | |
45 /* This solution risks heap growth in the presence of many dlopen */ | |
46 /* calls in either a multithreaded environment, or if the library */ | |
47 /* initialization code allocates substantial amounts of GC'ed memory. */ | |
48 /* But I don't know of a better solution. */ | |
49 static void disable_gc_for_dlopen() | |
50 { | |
51 LOCK(); | |
52 while (GC_incremental && GC_collection_in_progress()) { | |
53 GC_collect_a_little_inner(1000); | |
54 } | |
55 ++GC_dont_gc; | |
56 UNLOCK(); | |
57 } | |
58 | |
59 /* Redefine dlopen to guarantee mutual exclusion with */ | |
60 /* GC_register_dynamic_libraries. */ | |
61 /* Should probably happen for other operating systems, too. */ | |
62 | |
63 #include <dlfcn.h> | |
64 | |
65 #ifdef GC_USE_LD_WRAP | |
66 void * __wrap_dlopen(const char *path, int mode) | |
67 #else | |
68 void * GC_dlopen(path, mode) | |
69 GC_CONST char * path; | |
70 int mode; | |
71 #endif | |
72 { | |
73 void * result; | |
74 | |
75 # ifndef USE_PROC_FOR_LIBRARIES | |
76 disable_gc_for_dlopen(); | |
77 # endif | |
78 # ifdef GC_USE_LD_WRAP | |
79 result = (void *)__real_dlopen(path, mode); | |
80 # else | |
81 result = dlopen(path, mode); | |
82 # endif | |
83 # ifndef USE_PROC_FOR_LIBRARIES | |
84 GC_enable(); /* undoes disable_gc_for_dlopen */ | |
85 # endif | |
86 return(result); | |
87 } | |
88 # endif /* GC_PTHREADS || GC_SOLARIS_THREADS ... */ | |
89 | |
90 | |
91 |