summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2005-07-04 19:21:19 (UTC)
committer zautrix <zautrix>2005-07-04 19:21:19 (UTC)
commit16898aecbedb978169efef1e1e0233578a42a46e (patch) (unidiff)
treea391b6c44fd2df62daf5f643393af03bf051f4f0
parent2710cddd5b0b69efc1c5a7f8516d5b451ff258f1 (diff)
downloadkdepimpi-16898aecbedb978169efef1e1e0233578a42a46e.zip
kdepimpi-16898aecbedb978169efef1e1e0233578a42a46e.tar.gz
kdepimpi-16898aecbedb978169efef1e1e0233578a42a46e.tar.bz2
free ring buffer
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalmemory.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c
index 3ed38ad..d22561e 100644
--- a/libical/src/libical/icalmemory.c
+++ b/libical/src/libical/icalmemory.c
@@ -1,368 +1,368 @@
1/* -*- Mode: C -*- 1/* -*- Mode: C -*-
2 ====================================================================== 2 ======================================================================
3 FILE: icalmemory.c 3 FILE: icalmemory.c
4 CREATOR: eric 30 June 1999 4 CREATOR: eric 30 June 1999
5 5
6 $Id$ 6 $Id$
7 $Locker$ 7 $Locker$
8 8
9 The contents of this file are subject to the Mozilla Public License 9 The contents of this file are subject to the Mozilla Public License
10 Version 1.0 (the "License"); you may not use this file except in 10 Version 1.0 (the "License"); you may not use this file except in
11 compliance with the License. You may obtain a copy of the License at 11 compliance with the License. You may obtain a copy of the License at
12 http://www.mozilla.org/MPL/ 12 http://www.mozilla.org/MPL/
13 13
14 Software distributed under the License is distributed on an "AS IS" 14 Software distributed under the License is distributed on an "AS IS"
15 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 15 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
16 the License for the specific language governing rights and 16 the License for the specific language governing rights and
17 limitations under the License. 17 limitations under the License.
18 18
19 19
20 This program is free software; you can redistribute it and/or modify 20 This program is free software; you can redistribute it and/or modify
21 it under the terms of either: 21 it under the terms of either:
22 22
23 The LGPL as published by the Free Software Foundation, version 23 The LGPL as published by the Free Software Foundation, version
24 2.1, available at: http://www.fsf.org/copyleft/lesser.html 24 2.1, available at: http://www.fsf.org/copyleft/lesser.html
25 25
26 Or: 26 Or:
27 27
28 The Mozilla Public License Version 1.0. You may obtain a copy of 28 The Mozilla Public License Version 1.0. You may obtain a copy of
29 the License at http://www.mozilla.org/MPL/ 29 the License at http://www.mozilla.org/MPL/
30 30
31 The Original Code is icalmemory.h 31 The Original Code is icalmemory.h
32 32
33 ======================================================================*/ 33 ======================================================================*/
34 34
35/** 35/**
36 * @file icalmemory.c 36 * @file icalmemory.c
37 * @brief Common memory management routines. 37 * @brief Common memory management routines.
38 * 38 *
39 * libical often passes strings back to the caller. To make these 39 * libical often passes strings back to the caller. To make these
40 * interfaces simple, I did not want the caller to have to pass in a 40 * interfaces simple, I did not want the caller to have to pass in a
41 * memory buffer, but having libical pass out newly allocated memory 41 * memory buffer, but having libical pass out newly allocated memory
42 * makes it difficult to de-allocate the memory. 42 * makes it difficult to de-allocate the memory.
43 * 43 *
44 * The ring buffer in this scheme makes it possible for libical to pass 44 * The ring buffer in this scheme makes it possible for libical to pass
45 * out references to memory which the caller does not own, and be able 45 * out references to memory which the caller does not own, and be able
46 * to de-allocate the memory later. The ring allows libical to have 46 * to de-allocate the memory later. The ring allows libical to have
47 * several buffers active simultaneously, which is handy when creating 47 * several buffers active simultaneously, which is handy when creating
48 * string representations of components. 48 * string representations of components.
49 */ 49 */
50 50
51#define ICALMEMORY_C 51#define ICALMEMORY_C
52 52
53#ifdef HAVE_CONFIG_H 53#ifdef HAVE_CONFIG_H
54#include "config.h" 54#include "config.h"
55#endif 55#endif
56 56
57#ifdef DMALLOC 57#ifdef DMALLOC
58#include "dmalloc.h" 58#include "dmalloc.h"
59#endif 59#endif
60 60
61#include "icalmemory.h" 61#include "icalmemory.h"
62#include "icalerror.h" 62#include "icalerror.h"
63 63
64#include <stdio.h> /* for printf (debugging) */ 64#include <stdio.h> /* for printf (debugging) */
65#include <stdlib.h> /* for malloc, realloc */ 65#include <stdlib.h> /* for malloc, realloc */
66#include <string.h> /* for memset(), strdup */ 66#include <string.h> /* for memset(), strdup */
67 67
68#ifdef WIN32 68#ifdef WIN32
69#include <windows.h> 69#include <windows.h>
70#endif 70#endif
71 71
72#define BUFFER_RING_SIZE 100 72#define BUFFER_RING_SIZE 25
73#define MIN_BUFFER_SIZE 64 73#define MIN_BUFFER_SIZE 64
74 74
75 75
76/* HACK. Not threadsafe */ 76/* HACK. Not threadsafe */
77 77
78typedef struct { 78typedef struct {
79 int pos; 79 int pos;
80 void *ring[BUFFER_RING_SIZE]; 80 void *ring[BUFFER_RING_SIZE];
81} buffer_ring; 81} buffer_ring;
82 82
83void icalmemory_free_tmp_buffer (void* buf); 83void icalmemory_free_tmp_buffer (void* buf);
84void icalmemory_free_ring_byval(buffer_ring *br); 84void icalmemory_free_ring_byval(buffer_ring *br);
85 85
86static buffer_ring* global_buffer_ring = 0; 86static buffer_ring* global_buffer_ring = 0;
87 87
88#ifdef HAVE_PTHREAD 88#ifdef HAVE_PTHREAD
89#include <pthread.h> 89#include <pthread.h>
90 90
91static pthread_key_t ring_key; 91static pthread_key_t ring_key;
92static pthread_once_t ring_key_once = PTHREAD_ONCE_INIT; 92static pthread_once_t ring_key_once = PTHREAD_ONCE_INIT;
93 93
94static void ring_destroy(void * buf) { 94static void ring_destroy(void * buf) {
95 if (buf) icalmemory_free_ring_byval((buffer_ring *) buf); 95 if (buf) icalmemory_free_ring_byval((buffer_ring *) buf);
96 pthread_setspecific(ring_key, NULL); 96 pthread_setspecific(ring_key, NULL);
97} 97}
98 98
99static void ring_key_alloc(void) { 99static void ring_key_alloc(void) {
100 pthread_key_create(&ring_key, ring_destroy); 100 pthread_key_create(&ring_key, ring_destroy);
101} 101}
102#endif 102#endif
103 103
104 104
105static buffer_ring * buffer_ring_new(void) { 105static buffer_ring * buffer_ring_new(void) {
106 buffer_ring *br; 106 buffer_ring *br;
107 int i; 107 int i;
108 108
109 br = (buffer_ring *)malloc(sizeof(buffer_ring)); 109 br = (buffer_ring *)malloc(sizeof(buffer_ring));
110 110
111 for(i=0; i<BUFFER_RING_SIZE; i++){ 111 for(i=0; i<BUFFER_RING_SIZE; i++){
112 br->ring[i] = 0; 112 br->ring[i] = 0;
113 } 113 }
114 br->pos = 0; 114 br->pos = 0;
115 return(br); 115 return(br);
116} 116}
117 117
118 118
119#ifdef HAVE_PTHREAD 119#ifdef HAVE_PTHREAD
120static buffer_ring* get_buffer_ring_pthread(void) { 120static buffer_ring* get_buffer_ring_pthread(void) {
121 buffer_ring *br; 121 buffer_ring *br;
122 122
123 pthread_once(&ring_key_once, ring_key_alloc); 123 pthread_once(&ring_key_once, ring_key_alloc);
124 124
125 br = pthread_getspecific(ring_key); 125 br = pthread_getspecific(ring_key);
126 126
127 if (!br) { 127 if (!br) {
128 br = buffer_ring_new(); 128 br = buffer_ring_new();
129 pthread_setspecific(ring_key, br); 129 pthread_setspecific(ring_key, br);
130 } 130 }
131 return(br); 131 return(br);
132} 132}
133#endif 133#endif
134 134
135/* get buffer ring via a single global for a non-threaded program */ 135/* get buffer ring via a single global for a non-threaded program */
136static buffer_ring* get_buffer_ring_global(void) { 136static buffer_ring* get_buffer_ring_global(void) {
137 if (global_buffer_ring == 0) { 137 if (global_buffer_ring == 0) {
138 global_buffer_ring = buffer_ring_new(); 138 global_buffer_ring = buffer_ring_new();
139 } 139 }
140 return(global_buffer_ring); 140 return(global_buffer_ring);
141} 141}
142 142
143static buffer_ring *get_buffer_ring(void) { 143static buffer_ring *get_buffer_ring(void) {
144#ifdef HAVE_PTHREAD 144#ifdef HAVE_PTHREAD
145 return(get_buffer_ring_pthread()); 145 return(get_buffer_ring_pthread());
146#else 146#else
147 return get_buffer_ring_global(); 147 return get_buffer_ring_global();
148#endif 148#endif
149} 149}
150 150
151 151
152/** Add an existing buffer to the buffer ring */ 152/** Add an existing buffer to the buffer ring */
153void icalmemory_add_tmp_buffer(void* buf) 153void icalmemory_add_tmp_buffer(void* buf)
154{ 154{
155 buffer_ring *br = get_buffer_ring(); 155 buffer_ring *br = get_buffer_ring();
156 156
157 157
158 /* Wrap around the ring */ 158 /* Wrap around the ring */
159 if(++(br->pos) == BUFFER_RING_SIZE){ 159 if(++(br->pos) == BUFFER_RING_SIZE){
160 br->pos = 0; 160 br->pos = 0;
161 } 161 }
162 162
163 /* Free buffers as their slots are overwritten */ 163 /* Free buffers as their slots are overwritten */
164 if ( br->ring[br->pos] != 0){ 164 if ( br->ring[br->pos] != 0){
165 free( br->ring[br->pos]); 165 free( br->ring[br->pos]);
166 } 166 }
167 167
168 /* Assign the buffer to a slot */ 168 /* Assign the buffer to a slot */
169 br->ring[br->pos] = buf; 169 br->ring[br->pos] = buf;
170} 170}
171 171
172 172
173/** 173/**
174 * Create a new temporary buffer on the ring. Libical owns these and 174 * Create a new temporary buffer on the ring. Libical owns these and
175 * will deallocate them. 175 * will deallocate them.
176 */ 176 */
177 177
178void* 178void*
179icalmemory_tmp_buffer (size_t size) 179icalmemory_tmp_buffer (size_t size)
180{ 180{
181 char *buf; 181 char *buf;
182 182
183 if (size < MIN_BUFFER_SIZE){ 183 if (size < MIN_BUFFER_SIZE){
184 size = MIN_BUFFER_SIZE; 184 size = MIN_BUFFER_SIZE;
185 } 185 }
186 186
187 buf = (void*)malloc(size); 187 buf = (void*)malloc(size);
188 188
189 if( buf == 0){ 189 if( buf == 0){
190 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 190 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
191 return 0; 191 return 0;
192 } 192 }
193 193
194 memset(buf,0,size); 194 memset(buf,0,size);
195 195
196 icalmemory_add_tmp_buffer(buf); 196 icalmemory_add_tmp_buffer(buf);
197 197
198 return buf; 198 return buf;
199} 199}
200 200
201/** get rid of this buffer ring */ 201/** get rid of this buffer ring */
202void icalmemory_free_ring_byval(buffer_ring *br) { 202void icalmemory_free_ring_byval(buffer_ring *br) {
203 int i; 203 int i;
204 for(i=0; i<BUFFER_RING_SIZE; i++){ 204 for(i=0; i<BUFFER_RING_SIZE; i++){
205 if ( br->ring[i] != 0){ 205 if ( br->ring[i] != 0){
206 free( br->ring[i]); 206 free( br->ring[i]);
207 } 207 }
208 } 208 }
209 free(br); 209 free(br);
210} 210}
211 211
212void icalmemory_free_ring() 212void icalmemory_free_ring()
213{ 213{
214 buffer_ring *br; 214 buffer_ring *br;
215 br = get_buffer_ring(); 215 br = get_buffer_ring();
216 icalmemory_free_ring_byval(br); 216 icalmemory_free_ring_byval(br);
217 if ( global_buffer_ring == br ) 217 if ( global_buffer_ring == br )
218 global_buffer_ring = 0; 218 global_buffer_ring = 0;
219} 219}
220 220
221 221
222 222
223/** Like strdup, but the buffer is on the ring. */ 223/** Like strdup, but the buffer is on the ring. */
224char* 224char*
225icalmemory_tmp_copy(const char* str) 225icalmemory_tmp_copy(const char* str)
226{ 226{
227 char* b = icalmemory_tmp_buffer(strlen(str)+1); 227 char* b = icalmemory_tmp_buffer(strlen(str)+1);
228 228
229 strcpy(b,str); 229 strcpy(b,str);
230 230
231 return b; 231 return b;
232} 232}
233 233
234 234
235char* icalmemory_strdup(const char *s) 235char* icalmemory_strdup(const char *s)
236{ 236{
237 return strdup(s); 237 return strdup(s);
238} 238}
239 239
240void 240void
241icalmemory_free_tmp_buffer (void* buf) 241icalmemory_free_tmp_buffer (void* buf)
242{ 242{
243 if(buf == 0) 243 if(buf == 0)
244 { 244 {
245 return; 245 return;
246 } 246 }
247 247
248 free(buf); 248 free(buf);
249} 249}
250 250
251 251
252/* 252/*
253 * These buffer routines create memory the old fashioned way -- so the 253 * These buffer routines create memory the old fashioned way -- so the
254 * caller will have to deallocate the new memory 254 * caller will have to deallocate the new memory
255 */ 255 */
256 256
257void* icalmemory_new_buffer(size_t size) 257void* icalmemory_new_buffer(size_t size)
258{ 258{
259 void *b = malloc(size); 259 void *b = malloc(size);
260 260
261 if( b == 0){ 261 if( b == 0){
262 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 262 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
263 return 0; 263 return 0;
264 } 264 }
265 265
266 memset(b,0,size); 266 memset(b,0,size);
267 267
268 return b; 268 return b;
269} 269}
270 270
271void* icalmemory_resize_buffer(void* buf, size_t size) 271void* icalmemory_resize_buffer(void* buf, size_t size)
272{ 272{
273 void *b = realloc(buf, size); 273 void *b = realloc(buf, size);
274 274
275 if( b == 0){ 275 if( b == 0){
276 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 276 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
277 return 0; 277 return 0;
278 } 278 }
279 279
280 return b; 280 return b;
281} 281}
282 282
283void icalmemory_free_buffer(void* buf) 283void icalmemory_free_buffer(void* buf)
284{ 284{
285 free(buf); 285 free(buf);
286} 286}
287 287
288void 288void
289icalmemory_append_string(char** buf, char** pos, size_t* buf_size, 289icalmemory_append_string(char** buf, char** pos, size_t* buf_size,
290 const char* string) 290 const char* string)
291{ 291{
292 char *new_buf; 292 char *new_buf;
293 char *new_pos; 293 char *new_pos;
294 294
295 size_t data_length, final_length, string_length; 295 size_t data_length, final_length, string_length;
296 296
297#ifndef ICAL_NO_INTERNAL_DEBUG 297#ifndef ICAL_NO_INTERNAL_DEBUG
298 icalerror_check_arg_rv( (buf!=0),"buf"); 298 icalerror_check_arg_rv( (buf!=0),"buf");
299 icalerror_check_arg_rv( (*buf!=0),"*buf"); 299 icalerror_check_arg_rv( (*buf!=0),"*buf");
300 icalerror_check_arg_rv( (pos!=0),"pos"); 300 icalerror_check_arg_rv( (pos!=0),"pos");
301 icalerror_check_arg_rv( (*pos!=0),"*pos"); 301 icalerror_check_arg_rv( (*pos!=0),"*pos");
302 icalerror_check_arg_rv( (buf_size!=0),"buf_size"); 302 icalerror_check_arg_rv( (buf_size!=0),"buf_size");
303 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size"); 303 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size");
304 icalerror_check_arg_rv( (string!=0),"string"); 304 icalerror_check_arg_rv( (string!=0),"string");
305#endif 305#endif
306 306
307 string_length = strlen(string); 307 string_length = strlen(string);
308 data_length = (size_t)*pos - (size_t)*buf; 308 data_length = (size_t)*pos - (size_t)*buf;
309 final_length = data_length + string_length; 309 final_length = data_length + string_length;
310 310
311 if ( final_length >= (size_t) *buf_size) { 311 if ( final_length >= (size_t) *buf_size) {
312 312
313 313
314 *buf_size = (*buf_size) * 2 + final_length; 314 *buf_size = (*buf_size) * 2 + final_length;
315 315
316 new_buf = realloc(*buf,*buf_size); 316 new_buf = realloc(*buf,*buf_size);
317 317
318 new_pos = (void*)((size_t)new_buf + data_length); 318 new_pos = (void*)((size_t)new_buf + data_length);
319 319
320 *pos = new_pos; 320 *pos = new_pos;
321 *buf = new_buf; 321 *buf = new_buf;
322 } 322 }
323 323
324 strcpy(*pos, string); 324 strcpy(*pos, string);
325 325
326 *pos += string_length; 326 *pos += string_length;
327} 327}
328 328
329 329
330void 330void
331icalmemory_append_char(char** buf, char** pos, size_t* buf_size, 331icalmemory_append_char(char** buf, char** pos, size_t* buf_size,
332 char ch) 332 char ch)
333{ 333{
334 char *new_buf; 334 char *new_buf;
335 char *new_pos; 335 char *new_pos;
336 336
337 size_t data_length, final_length; 337 size_t data_length, final_length;
338 338
339#ifndef ICAL_NO_INTERNAL_DEBUG 339#ifndef ICAL_NO_INTERNAL_DEBUG
340 icalerror_check_arg_rv( (buf!=0),"buf"); 340 icalerror_check_arg_rv( (buf!=0),"buf");
341 icalerror_check_arg_rv( (*buf!=0),"*buf"); 341 icalerror_check_arg_rv( (*buf!=0),"*buf");
342 icalerror_check_arg_rv( (pos!=0),"pos"); 342 icalerror_check_arg_rv( (pos!=0),"pos");
343 icalerror_check_arg_rv( (*pos!=0),"*pos"); 343 icalerror_check_arg_rv( (*pos!=0),"*pos");
344 icalerror_check_arg_rv( (buf_size!=0),"buf_size"); 344 icalerror_check_arg_rv( (buf_size!=0),"buf_size");
345 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size"); 345 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size");
346#endif 346#endif
347 347
348 data_length = (size_t)*pos - (size_t)*buf; 348 data_length = (size_t)*pos - (size_t)*buf;
349 349
350 final_length = data_length + 2; 350 final_length = data_length + 2;
351 351
352 if ( final_length > (size_t) *buf_size ) { 352 if ( final_length > (size_t) *buf_size ) {
353 353
354 354
355 *buf_size = (*buf_size) * 2 + final_length +1; 355 *buf_size = (*buf_size) * 2 + final_length +1;
356 356
357 new_buf = realloc(*buf,*buf_size); 357 new_buf = realloc(*buf,*buf_size);
358 358
359 new_pos = (void*)((size_t)new_buf + data_length); 359 new_pos = (void*)((size_t)new_buf + data_length);
360 360
361 *pos = new_pos; 361 *pos = new_pos;
362 *buf = new_buf; 362 *buf = new_buf;
363 } 363 }
364 364
365 **pos = ch; 365 **pos = ch;
366 *pos += 1; 366 *pos += 1;
367 **pos = 0; 367 **pos = 0;
368} 368}