1 #include "config.h"
2 #include <string.h>
3 #include <orbit/orbit.h>
4 #include "orb-core-private.h"
5
6 /***
7 The argument {mem} is a chuck of memory described by {tc}, and its
8 contents is freed, but {mem} itself is not freed. That is, if {mem}
9 contains anything interesting (objrefs, pointers), they are freed.
10 A pointer to the end of {mem} is returned. This should always be
11 the same as {mem + ORBit_gather_alloc_info(tc)}. Also, any pointers
12 within {mem} are zeroed; thus it should be safe to call this
13 function multiple times on the same chunk of memory.
14
15 This function is a modified version of ORBit_free_via_TypeCode().
16 Aside from the arguments, the bigest difference is that this
17 does not free the {tc} which is passed in. The old style led
18 to a lot of pointless dups, and also failed miserably when
19 arrays of things were allocated.
20 **/
21 static gpointer
ORBit_freekids_via_TypeCode_T(gpointer mem,CORBA_TypeCode tc)22 ORBit_freekids_via_TypeCode_T (gpointer mem,
23 CORBA_TypeCode tc)
24 {
25 int i;
26 guchar *retval = NULL;
27 CORBA_TypeCode subtc;
28
29 /* g_warning ("Freeing via tc '%s' at %p",
30 ORBit_tk_to_name (tc->kind), mem);*/
31
32 switch (tc->kind) {
33 case CORBA_tk_any: {
34 CORBA_any *pval = mem;
35 if (pval->_release)
36 ORBit_free_T (pval->_value);
37 pval->_value = NULL;
38 ORBit_RootObject_release_T (pval->_type);
39 pval->_type = NULL;
40 retval = (guchar *) (pval + 1);
41 break;
42 }
43 case CORBA_tk_TypeCode:
44 case CORBA_tk_objref: {
45 CORBA_Object *pval = mem;
46
47 ORBit_RootObject_release_T (*pval);
48 *pval = NULL;
49 retval = ((guchar *)mem) + sizeof (*pval);
50 break;
51 }
52 case CORBA_tk_Principal: {
53 CORBA_Principal *pval = mem;
54 if (pval->_release)
55 ORBit_free_T (pval->_buffer);
56 pval->_buffer = NULL;
57 retval = (guchar *)(pval + 1);
58 break;
59 }
60 case CORBA_tk_except:
61 case CORBA_tk_struct:
62 mem = ALIGN_ADDRESS (mem, tc->c_align);
63 for (i = 0; i < tc->sub_parts; i++) {
64 subtc = tc->subtypes [i];
65 mem = ALIGN_ADDRESS (mem, subtc->c_align);
66 mem = ORBit_freekids_via_TypeCode_T (mem, subtc);
67 }
68 mem = ALIGN_ADDRESS (mem, tc->c_align);
69 retval = mem;
70 break;
71 case CORBA_tk_union: {
72 int sz = 0;
73 int al = 1;
74 gconstpointer cmem;
75
76 cmem = ALIGN_ADDRESS (mem, MAX (tc->discriminator->c_align,
77 tc->c_align));
78 subtc = ORBit_get_union_tag (tc, &cmem, TRUE);
79 for (i = 0; i < tc->sub_parts; i++) {
80 al = MAX (al, tc->subtypes [i]->c_align);
81 sz = MAX (sz, ORBit_gather_alloc_info (tc->subtypes [i]));
82 }
83 mem = ALIGN_ADDRESS (cmem, al);
84 ORBit_freekids_via_TypeCode_T (mem, subtc);
85 /* the end of the body (subtc) may not be the
86 * same as the end of the union */
87 retval = ((guchar *)mem) + sz;
88 break;
89 }
90 case CORBA_tk_wstring:
91 case CORBA_tk_string: {
92 CORBA_char **pval = mem;
93 ORBit_free_T (*pval);
94 *pval = NULL;
95 retval = (guchar *)mem + sizeof (*pval);
96 break;
97 }
98 case CORBA_tk_sequence: {
99 CORBA_sequence_CORBA_octet *pval = mem;
100 if (pval->_release)
101 ORBit_free_T (pval->_buffer);
102 pval->_buffer = NULL;
103 retval = (guchar *)mem + sizeof(*pval);
104 break;
105 }
106 case CORBA_tk_array:
107 for (i = 0; i < tc->length; i++)
108 mem = ORBit_freekids_via_TypeCode_T(
109 mem, tc->subtypes[0]);
110 retval = mem;
111 break;
112 case CORBA_tk_alias:
113 retval = ORBit_freekids_via_TypeCode_T (
114 mem, tc->subtypes[0]);
115 break;
116 default: {
117 gulong length;
118 length = ORBit_gather_alloc_info (tc);
119 retval = (guchar *) ALIGN_ADDRESS (mem, tc->c_align) + length;
120 break;
121 }
122 }
123 return retval;
124 }
125
126 gpointer
ORBit_freekids_via_TypeCode(CORBA_TypeCode tc,gpointer mem)127 ORBit_freekids_via_TypeCode (CORBA_TypeCode tc, gpointer mem)
128 {
129 gpointer ret;
130
131 LINK_MUTEX_LOCK (ORBit_RootObject_lifecycle_lock);
132
133 ret = ORBit_freekids_via_TypeCode_T (mem, tc);
134
135 LINK_MUTEX_UNLOCK (ORBit_RootObject_lifecycle_lock);
136
137 return ret;
138 }
139
140 void
CORBA_free(gpointer mem)141 CORBA_free (gpointer mem)
142 {
143 ORBit_free (mem);
144 }
145
146 #define SHORT_PREFIX_LEN (MAX (sizeof (ORBitMemHow), \
147 ORBIT_ALIGNOF_CORBA_LONG_DOUBLE))
148 #define LONG_PREFIX_LEN (sizeof (CORBA_long_double) > sizeof (ORBit_MemPrefix) ? \
149 ORBIT_ALIGNOF_CORBA_LONG_DOUBLE : \
150 MAX (sizeof (ORBit_MemPrefix), \
151 sizeof (CORBA_long_double) + \
152 ORBIT_ALIGNOF_CORBA_LONG_DOUBLE))
153
154 void
ORBit_free_T(gpointer mem)155 ORBit_free_T (gpointer mem)
156 {
157 int i;
158 guchar *x;
159 CORBA_TypeCode tc;
160 ORBitMemHow how;
161 ORBit_MemPrefix *prefix;
162 ORBit_Mem_free_fn free_fn;
163
164 if (!mem)
165 return;
166
167 if ((gulong)mem & 0x1) {
168 g_free ((guchar *)mem - 1);
169 return;
170 }
171
172 how = *(((ORBitMemHow *) mem) - 1);
173
174 switch (ORBIT_MEMHOW_HOW (how)) {
175 case ORBIT_MEMHOW_TYPECODE:
176 prefix = (ORBit_MemPrefix *)
177 ((guchar *) mem - LONG_PREFIX_LEN);
178
179 free_fn = (ORBit_Mem_free_fn)
180 ORBit_freekids_via_TypeCode_T;
181 tc = prefix->u.tc;
182 break;
183
184 case ORBIT_MEMHOW_FREEFNC:
185 prefix = (ORBit_MemPrefix *)
186 ((guchar *) mem - LONG_PREFIX_LEN);
187
188 free_fn = prefix->u.free_fn;
189 tc = NULL;
190 break;
191 case ORBIT_MEMHOW_SIMPLE:
192 g_free ((guchar *)mem - SHORT_PREFIX_LEN);
193 return;
194 case ORBIT_MEMHOW_NONE:
195 default:
196 return;
197 }
198
199 how = ORBIT_MEMHOW_ELEMENTS (how);
200
201 for (i = 0, x = mem; i < how; i++)
202 x = free_fn (x, tc);
203
204 g_free (prefix);
205
206 if (tc)
207 ORBit_RootObject_release_T (tc);
208 }
209
210 void
ORBit_free(gpointer mem)211 ORBit_free (gpointer mem)
212 {
213 if (!mem)
214 return;
215
216 LINK_MUTEX_LOCK (ORBit_RootObject_lifecycle_lock);
217
218 ORBit_free_T (mem);
219
220 LINK_MUTEX_UNLOCK (ORBit_RootObject_lifecycle_lock);
221 }
222
223 CORBA_char *
ORBit_alloc_string(size_t string_length)224 ORBit_alloc_string (size_t string_length)
225 {
226 guchar *mem;
227
228 mem = g_malloc (string_length + 1);
229
230 return (CORBA_char *)(mem + 1);
231 }
232
233 gpointer
ORBit_alloc_simple(size_t block_size)234 ORBit_alloc_simple (size_t block_size)
235 {
236 guchar *mem, *prefix;
237
238 if (!block_size)
239 return NULL;
240
241 prefix = g_malloc (SHORT_PREFIX_LEN + block_size);
242
243 mem = (guchar *) prefix + SHORT_PREFIX_LEN;
244
245 *((ORBitMemHow *)mem - 1) = ORBIT_MEMHOW_SIMPLE;
246
247 return mem;
248 }
249
250 gpointer
ORBit_alloc_with_free_fn(size_t element_size,guint num_elements,ORBit_Mem_free_fn free_fn)251 ORBit_alloc_with_free_fn (size_t element_size,
252 guint num_elements,
253 ORBit_Mem_free_fn free_fn)
254 {
255 guchar *mem;
256 ORBit_MemPrefix *prefix;
257
258 if (!num_elements)
259 return NULL;
260
261 prefix = g_malloc (LONG_PREFIX_LEN +
262 element_size * num_elements);
263 prefix->u.free_fn = free_fn;
264
265 mem = (guchar *) prefix + LONG_PREFIX_LEN;
266
267 *((ORBitMemHow *)mem - 1) = ORBIT_MEMHOW_MAKE (
268 ORBIT_MEMHOW_FREEFNC, num_elements);
269
270 return mem;
271 }
272
273 gpointer
ORBit_alloc_tcval(CORBA_TypeCode tc,guint num_elements)274 ORBit_alloc_tcval (CORBA_TypeCode tc,
275 guint num_elements)
276 {
277 guchar *mem;
278 guint element_size;
279 ORBit_MemPrefix *prefix;
280
281 if (!num_elements)
282 return NULL;
283
284 if (!(element_size = ORBit_gather_alloc_info (tc)))
285 return NULL;
286
287 prefix = g_malloc0 (LONG_PREFIX_LEN +
288 element_size * num_elements);
289
290 prefix->u.tc = ORBit_RootObject_duplicate (tc);
291
292 mem = (guchar *)prefix + LONG_PREFIX_LEN;
293
294 *((ORBitMemHow *)mem - 1) = ORBIT_MEMHOW_MAKE (
295 ORBIT_MEMHOW_TYPECODE, num_elements);
296
297 return mem;
298 }
299
300 gpointer
ORBit_realloc_tcval(gpointer old,CORBA_TypeCode tc,guint old_num_elements,guint num_elements)301 ORBit_realloc_tcval (gpointer old,
302 CORBA_TypeCode tc,
303 guint old_num_elements,
304 guint num_elements)
305 {
306 guint element_size;
307 ORBit_MemPrefix *prefix;
308 guchar *mem;
309
310 g_assert (num_elements > old_num_elements);
311
312 if (!num_elements)
313 return NULL;
314
315 if (!old_num_elements && !old)
316 return ORBit_alloc_tcval (tc, num_elements);
317
318 if (!(element_size = ORBit_gather_alloc_info (tc)))
319 return NULL;
320
321 prefix = g_realloc ((guchar *) old - LONG_PREFIX_LEN,
322 LONG_PREFIX_LEN +
323 element_size * num_elements);
324
325 /* Initialize as yet unused memory to 'safe' values */
326 memset ((guchar *) prefix + LONG_PREFIX_LEN +
327 old_num_elements * element_size,
328 0, (num_elements - old_num_elements) * element_size);
329
330 mem = (guchar *)prefix + LONG_PREFIX_LEN;
331
332 *((ORBitMemHow *)mem - 1) = ORBIT_MEMHOW_MAKE (
333 ORBIT_MEMHOW_TYPECODE, num_elements);
334
335 return mem;
336 }
337
338 CORBA_TypeCode
ORBit_alloc_get_tcval(gpointer mem)339 ORBit_alloc_get_tcval (gpointer mem)
340 {
341 ORBitMemHow how;
342 ORBit_MemPrefix *prefix;
343
344 if (!mem)
345 return NULL;
346
347 if ((gulong)mem & 0x1)
348 return TC_CORBA_string;
349
350 how = *(((ORBitMemHow *) mem) - 1);
351
352 if (ORBIT_MEMHOW_HOW (how) == ORBIT_MEMHOW_TYPECODE) {
353 prefix = (ORBit_MemPrefix *)
354 ((guchar *) mem - LONG_PREFIX_LEN);
355
356 return ORBit_RootObject_duplicate (prefix->u.tc);
357 } else
358 g_error ("Can't determine type of %p (%u)", mem, how);
359
360 return NULL;
361 }
362
363 gpointer
ORBit_alloc_by_tc(CORBA_TypeCode tc)364 ORBit_alloc_by_tc (CORBA_TypeCode tc)
365 {
366 guchar *mem;
367 guint size;
368 ORBit_MemPrefix *prefix;
369
370 if (!(size = ORBit_gather_alloc_info (tc)))
371 return NULL;
372
373 prefix = g_malloc0 (LONG_PREFIX_LEN + size);
374
375 prefix->u.tc = ORBit_RootObject_duplicate (tc);
376
377 mem = (guchar *)prefix + LONG_PREFIX_LEN;
378
379 *((ORBitMemHow *)mem - 1) = ORBIT_MEMHOW_MAKE (
380 ORBIT_MEMHOW_TYPECODE, 1);
381
382 return mem;
383 }
384