aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamiro Polla <ramiro.polla@gmail.com>2007-06-29 23:42:51 +0000
committerRamiro Polla <ramiro.polla@gmail.com>2007-06-29 23:42:51 +0000
commit66a5baf77798bbf9dbfe1d7ddf6c591843d831c7 (patch)
treee9717c0daf0b316d139c5a2a535c1d6f9880f701
parent40f1a4cc1e80c496aaab4f76a88810273ee0b15f (diff)
downloaddlfcn-win32-66a5baf77798bbf9dbfe1d7ddf6c591843d831c7.tar.gz
dlfcn-win32-66a5baf77798bbf9dbfe1d7ddf6c591843d831c7.tar.bz2
dlfcn-win32-66a5baf77798bbf9dbfe1d7ddf6c591843d831c7.zip
Use double linked list instead of static array of 255 global objects.
-rw-r--r--dlfcn.c103
1 files changed, 68 insertions, 35 deletions
diff --git a/dlfcn.c b/dlfcn.c
index 4c82304..f0efc22 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -27,43 +27,76 @@
27 * any kind of thread safety. 27 * any kind of thread safety.
28 */ 28 */
29 29
30/* I have no special reason to have set MAX_GLOBAL_OBJECTS to this value. Any 30typedef struct global_object {
31 * comments are welcome. 31 HMODULE hModule;
32 */ 32 struct global_object *previous;
33#define MAX_OBJECTS 255 33 struct global_object *next;
34} global_object;
34 35
35static HMODULE global_objects[MAX_OBJECTS]; 36static global_object first_object;
36 37
37/* This function adds an object to the list of global objects. 38/* These functions implement a double linked list for the global objects. */
38 * The implementation is very simple and slow. 39static global_object *global_search( HMODULE hModule )
39 * TODO: should failing this function be enough to fail the call to dlopen( )?
40 */
41static void global_object_add( HMODULE hModule )
42{ 40{
43 int i; 41 global_object *pobject;
44 42
45 for( i = 0 ; i < MAX_OBJECTS ; i++ ) 43 if( hModule == NULL )
46 { 44 return NULL;
47 if( !global_objects[i] ) 45
48 { 46 for( pobject = &first_object; pobject ; pobject = pobject->next )
49 global_objects[i] = hModule; 47 if( pobject->hModule == hModule )
50 break; 48 return pobject;
51 } 49
52 } 50 return NULL;
53} 51}
54 52
55static void global_object_rem( HMODULE hModule ) 53static void global_add( HMODULE hModule )
56{ 54{
57 int i; 55 global_object *pobject;
56 global_object *nobject;
58 57
59 for( i = 0 ; i < MAX_OBJECTS ; i++ ) 58 if( hModule == NULL )
60 { 59 return;
61 if( global_objects[i] == hModule ) 60
62 { 61 pobject = global_search( hModule );
63 global_objects[i] = 0; 62
64 break; 63 /* Do not add object again if it's already on the list */
65 } 64 if( pobject )
66 } 65 return;
66
67 for( pobject = &first_object; pobject->next ; pobject = pobject->next );
68
69 nobject = malloc( sizeof(global_object) );
70
71 /* Should this be enough to fail global_add, and therefore also fail
72 * dlopen?
73 */
74 if( !nobject )
75 return;
76
77 pobject->next = nobject;
78 nobject->previous = pobject;
79 nobject->hModule = hModule;
80}
81
82static void global_rem( HMODULE hModule )
83{
84 global_object *pobject;
85
86 if( hModule == NULL )
87 return;
88
89 pobject = global_search( hModule );
90
91 if( !pobject )
92 return;
93
94 if( pobject->next )
95 pobject->next->previous = pobject->previous;
96 if( pobject->previous )
97 pobject->previous->next = pobject->next;
98
99 free( pobject );
67} 100}
68 101
69/* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one 102/* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one
@@ -191,7 +224,7 @@ void *dlopen( const char *file, int mode )
191 if( !hModule ) 224 if( !hModule )
192 save_err_str( lpFileName ); 225 save_err_str( lpFileName );
193 else if( (mode & RTLD_GLOBAL) ) 226 else if( (mode & RTLD_GLOBAL) )
194 global_object_add( hModule ); 227 global_add( hModule );
195 } 228 }
196 229
197 /* Return to previous state of the error-mode bit flags. */ 230 /* Return to previous state of the error-mode bit flags. */
@@ -213,7 +246,7 @@ int dlclose( void *handle )
213 * objects. 246 * objects.
214 */ 247 */
215 if( ret ) 248 if( ret )
216 global_object_rem( hModule ); 249 global_rem( hModule );
217 else 250 else
218 save_err_ptr( handle ); 251 save_err_ptr( handle );
219 252
@@ -243,13 +276,13 @@ void *dlsym( void *handle, const char *name )
243 276
244 if( hModule == handle ) 277 if( hModule == handle )
245 { 278 {
246 int i; 279 global_object *pobject;
247 280
248 for( i = 0 ; i < MAX_OBJECTS ; i++ ) 281 for( pobject = &first_object; pobject ; pobject = pobject->next )
249 { 282 {
250 if( global_objects[i] != 0 ) 283 if( pobject->hModule )
251 { 284 {
252 symbol = GetProcAddress( global_objects[i], name ); 285 symbol = GetProcAddress( pobject->hModule, name );
253 if( symbol != NULL ) 286 if( symbol != NULL )
254 break; 287 break;
255 } 288 }