This source file includes following definitions.
- loader_callback
- lt_dlloader_add
- loader_dump_callback
- lt_dlloader_dump
- lt_dlloader_next
- lt_dlloader_get
- lt_dlloader_remove
- lt_dlloader_find
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include "lt__private.h"
32 #include "lt_dlloader.h"
33
34 #define RETURN_SUCCESS 0
35 #define RETURN_FAILURE 1
36
37 static void * loader_callback (SList *item, void *userdata);
38
39
40
41 static SList *loaders = 0;
42
43
44
45
46
47 static void *
48 loader_callback (SList *item, void *userdata)
49 {
50 const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
51 const char * name = (const char *) userdata;
52
53 assert (vtable);
54
55 return streq (vtable->name, name) ? (void *) item : NULL;
56 }
57
58
59
60
61 int
62 lt_dlloader_add (const lt_dlvtable *vtable)
63 {
64 SList *item;
65
66 if ((vtable == 0)
67 || (vtable->module_open == 0)
68 || (vtable->module_close == 0)
69 || (vtable->find_sym == 0)
70 || ((vtable->priority != LT_DLLOADER_PREPEND) &&
71 (vtable->priority != LT_DLLOADER_APPEND)))
72 {
73 LT__SETERROR (INVALID_LOADER);
74 return RETURN_FAILURE;
75 }
76
77 item = slist_box (vtable);
78 if (!item)
79 {
80 (*lt__alloc_die) ();
81
82
83
84 return RETURN_FAILURE;
85 }
86
87 if (vtable->priority == LT_DLLOADER_PREPEND)
88 {
89 loaders = slist_cons (item, loaders);
90 }
91 else
92 {
93 assert (vtable->priority == LT_DLLOADER_APPEND);
94 loaders = slist_concat (loaders, item);
95 }
96
97 return RETURN_SUCCESS;
98 }
99
100 #ifdef LT_DEBUG_LOADERS
101 static void *
102 loader_dump_callback (SList *item, void *userdata)
103 {
104 const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
105 fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)");
106 return 0;
107 }
108
109 void
110 lt_dlloader_dump (void)
111 {
112 fprintf (stderr, "loaders: ");
113 if (!loaders)
114 {
115 fprintf (stderr, "(empty)");
116 }
117 else
118 {
119 const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata;
120 fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)");
121 if (slist_tail (loaders))
122 slist_foreach (slist_tail (loaders), loader_dump_callback, NULL);
123 }
124 fprintf (stderr, "\n");
125 }
126 #endif
127
128
129
130 lt_dlloader
131 lt_dlloader_next (lt_dlloader loader)
132 {
133 SList *item = (SList *) loader;
134 return (lt_dlloader) (item ? item->next : loaders);
135 }
136
137
138
139 const lt_dlvtable *
140 lt_dlloader_get (lt_dlloader loader)
141 {
142 return (const lt_dlvtable *) (loader ? ((SList *) loader)->userdata : NULL);
143 }
144
145
146
147
148
149
150
151
152 lt_dlvtable *
153 lt_dlloader_remove (const char *name)
154 {
155 const lt_dlvtable * vtable = lt_dlloader_find (name);
156 static const char id_string[] = "lt_dlloader_remove";
157 lt_dlinterface_id iface;
158 lt_dlhandle handle = 0;
159 int in_use = 0;
160 int in_use_by_resident = 0;
161
162 if (!vtable)
163 {
164 LT__SETERROR (INVALID_LOADER);
165 return 0;
166 }
167
168
169 iface = lt_dlinterface_register (id_string, NULL);
170 if (!iface)
171
172 return 0;
173
174 while ((handle = lt_dlhandle_iterate (iface, handle)))
175 {
176 lt_dlhandle cur = handle;
177 if (cur->vtable == vtable)
178 {
179 in_use = 1;
180 if (lt_dlisresident (handle))
181 in_use_by_resident = 1;
182 }
183 }
184 lt_dlinterface_free (iface);
185 if (in_use)
186 {
187 if (!in_use_by_resident)
188 LT__SETERROR (REMOVE_LOADER);
189 return 0;
190 }
191
192
193 if (vtable && vtable->dlloader_exit)
194 {
195 if ((*vtable->dlloader_exit) (vtable->dlloader_data) != 0)
196 {
197
198
199
200 return 0;
201 }
202 }
203
204
205 return (lt_dlvtable *)
206 slist_unbox ((SList *) slist_remove (&loaders, loader_callback, (void *) name));
207 }
208
209
210 const lt_dlvtable *
211 lt_dlloader_find (const char *name)
212 {
213 return lt_dlloader_get (slist_find (loaders, loader_callback, (void *) name));
214 }