1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | #include "priv.h" |
22 | |
23 | |
24 | struct aux |
25 | { |
26 | void (*free_el)(); |
27 | unsigned refs; |
28 | }; |
29 | |
30 | |
31 | |
32 | |
33 | struct port_class **trivfs_dynamic_protid_port_classes = 0; |
34 | size_t trivfs_num_dynamic_protid_port_classes = 0; |
35 | static struct aux *dynamic_protid_port_classes_aux = 0; |
36 | static size_t dynamic_protid_port_classes_sz = 0; |
37 | |
38 | |
39 | struct port_class **trivfs_dynamic_control_port_classes = 0; |
40 | size_t trivfs_num_dynamic_control_port_classes = 0; |
41 | static struct aux *dynamic_control_port_classes_aux = 0; |
42 | static size_t dynamic_control_port_classes_sz = 0; |
43 | |
44 | |
45 | struct port_bucket **trivfs_dynamic_port_buckets = 0; |
46 | size_t trivfs_num_dynamic_port_buckets = 0; |
47 | static struct aux *dynamic_port_buckets_aux = 0; |
48 | static size_t dynamic_port_buckets_sz = 0; |
49 | |
50 | |
51 | static pthread_mutex_t dyn_lock = PTHREAD_MUTEX_INITIALIZER{ ((__pthread_spinlock_t) 0), ((__pthread_spinlock_t) 0), 0, 0 , 0, 0, 0, 0 }; |
52 | |
53 |
|
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | static error_t |
66 | add_el (void *el, void (*free_el)(), |
67 | void *vec_v, struct aux **aux_vec, |
68 | size_t *sz, size_t *num) |
69 | { |
70 | int i; |
71 | size_t new_sz; |
72 | void ***vec, **new_vec; |
73 | struct aux *new_aux_vec; |
74 | |
75 | if (! el) |
| |
76 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
77 | |
78 | pthread_mutex_lock (&dyn_lock); |
79 | |
80 | vec = vec_v; |
81 | |
82 | for (i = 0; i < *sz; i++) |
| 4 | | Loop condition is false. Execution continues on line 99 | |
|
83 | if (! (*vec)[i]) |
84 | { |
85 | (*vec)[i] = el; |
86 | (*aux_vec)[i].free_el = free_el; |
87 | (*aux_vec)[i].refs = 1; |
88 | (*num)++; |
89 | pthread_mutex_unlock (&dyn_lock); |
90 | return 0; |
91 | } |
92 | else if ((*vec)[i] == el) |
93 | { |
94 | (*aux_vec)[i].refs++; |
95 | pthread_mutex_unlock (&dyn_lock); |
96 | return 0; |
97 | } |
98 | |
99 | new_sz = *sz + 4; |
100 | new_vec = realloc (*vec, new_sz * sizeof (void *)); |
| |
101 | new_aux_vec = realloc (*aux_vec, new_sz * sizeof (struct aux)); |
102 | |
103 | if (!new_vec || !new_aux_vec) |
| 6 | | Assuming 'new_vec' is non-null | |
|
| 7 | | Assuming 'new_aux_vec' is null | |
|
| |
104 | { |
105 | if (free_el) |
| 9 | | Memory is never released; potential leak of memory pointed to by 'new_vec' |
|
106 | (*free_el) (el); |
107 | |
108 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
109 | } |
110 | |
111 | for (i = *sz; i < new_sz; i++) |
112 | new_vec[i] = 0; |
113 | |
114 | new_vec[*sz] = el; |
115 | new_aux_vec[*sz].free_el = free_el; |
116 | new_aux_vec[*sz].refs = 1; |
117 | (*num)++; |
118 | |
119 | *vec = new_vec; |
120 | *aux_vec = new_aux_vec; |
121 | *sz = new_sz; |
122 | |
123 | pthread_mutex_unlock (&dyn_lock); |
124 | |
125 | return 0; |
126 | } |
127 | |
128 | |
129 | |
130 | |
131 | |
132 | static void |
133 | drop_el (void *el, void *vec_v, struct aux *aux_vec, |
134 | size_t sz, size_t *num) |
135 | { |
136 | int i; |
137 | void **vec; |
138 | |
139 | if (! el) |
140 | return; |
141 | |
142 | pthread_mutex_lock (&dyn_lock); |
143 | |
144 | vec = vec_v; |
145 | |
146 | for (i = 0; i < sz; i++) |
147 | if (vec[i] == el) |
148 | { |
149 | if (aux_vec[i].refs == 1) |
150 | { |
151 | if (aux_vec[i].free_el) |
152 | (*aux_vec[i].free_el) (el); |
153 | vec[i] = 0; |
154 | (*num)--; |
155 | } |
156 | else |
157 | aux_vec[i].refs--; |
158 | break; |
159 | } |
160 | |
161 | pthread_mutex_unlock (&dyn_lock); |
162 | } |
163 |
|
164 | |
165 | |
166 | |
167 | error_t |
168 | trivfs_add_control_port_class (struct port_class **class) |
169 | { |
170 | |
171 | |
172 | |
173 | if (! *class) |
174 | { |
175 | *class = ports_create_class (trivfs_clean_cntl, 0); |
176 | if (! *class) |
177 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
178 | } |
179 | |
180 | return |
181 | add_el (*class, 0, |
182 | &trivfs_dynamic_control_port_classes, |
183 | &dynamic_control_port_classes_aux, |
184 | &dynamic_control_port_classes_sz, |
185 | &trivfs_num_dynamic_control_port_classes); |
186 | } |
187 | |
188 | |
189 | |
190 | void |
191 | trivfs_remove_control_port_class (struct port_class *class) |
192 | { |
193 | drop_el (class, |
194 | trivfs_dynamic_control_port_classes, |
195 | dynamic_control_port_classes_aux, |
196 | dynamic_control_port_classes_sz, |
197 | &trivfs_num_dynamic_control_port_classes); |
198 | } |
199 |
|
200 | |
201 | |
202 | |
203 | error_t |
204 | trivfs_add_protid_port_class (struct port_class **class) |
205 | { |
206 | |
207 | |
208 | |
209 | if (! *class) |
210 | { |
211 | *class = ports_create_class (trivfs_clean_protid, 0); |
212 | if (! *class) |
213 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
214 | } |
215 | |
216 | return |
217 | add_el (*class, 0, |
218 | &trivfs_dynamic_protid_port_classes, |
219 | &dynamic_protid_port_classes_aux, |
220 | &dynamic_protid_port_classes_sz, |
221 | &trivfs_num_dynamic_protid_port_classes); |
222 | } |
223 | |
224 | |
225 | |
226 | void |
227 | trivfs_remove_protid_port_class (struct port_class *class) |
228 | { |
229 | drop_el (class, |
230 | trivfs_dynamic_protid_port_classes, |
231 | dynamic_protid_port_classes_aux, |
232 | dynamic_protid_port_classes_sz, |
233 | &trivfs_num_dynamic_protid_port_classes); |
234 | } |
235 |
|
236 | |
237 | |
238 | |
239 | error_t |
240 | trivfs_add_port_bucket (struct port_bucket **bucket) |
241 | { |
242 | |
243 | |
244 | |
245 | if (! *bucket) |
| |
246 | { |
247 | *bucket = ports_create_bucket (); |
248 | if (! *bucket) |
249 | return ENOMEM((0x10 << 26) | ((12) & 0x3fff)); |
250 | } |
251 | |
252 | return |
253 | add_el (*bucket, 0, |
| |
254 | &trivfs_dynamic_port_buckets, |
255 | &dynamic_port_buckets_aux, |
256 | &dynamic_port_buckets_sz, |
257 | &trivfs_num_dynamic_port_buckets); |
258 | } |
259 | |
260 | |
261 | |
262 | void |
263 | trivfs_remove_port_bucket (struct port_bucket *bucket) |
264 | { |
265 | drop_el (bucket, |
266 | trivfs_dynamic_port_buckets, |
267 | dynamic_port_buckets_aux, |
268 | dynamic_port_buckets_sz, |
269 | &trivfs_num_dynamic_port_buckets); |
270 | } |