summaryrefslogtreecommitdiffabout
path: root/libical/src
authorzautrix <zautrix>2005-07-04 19:16:55 (UTC)
committer zautrix <zautrix>2005-07-04 19:16:55 (UTC)
commit4f3238355f67a256f338986ca13322ef23960895 (patch) (unidiff)
tree023eabaf2c42d2c58753e5a3f9c5c680f132fbf8 /libical/src
parentb0ed0793fa5d27475d8954a683ea68ca9ac0017f (diff)
downloadkdepimpi-4f3238355f67a256f338986ca13322ef23960895.zip
kdepimpi-4f3238355f67a256f338986ca13322ef23960895.tar.gz
kdepimpi-4f3238355f67a256f338986ca13322ef23960895.tar.bz2
free ring buffer
Diffstat (limited to 'libical/src') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalmemory.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c
index 058ef37..18d7ef9 100644
--- a/libical/src/libical/icalmemory.c
+++ b/libical/src/libical/icalmemory.c
@@ -1,313 +1,314 @@
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 2500 72#define BUFFER_RING_SIZE 50
73#define MIN_BUFFER_SIZE 200 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
217 icalmemory_free_ring_byval(br); 216 icalmemory_free_ring_byval(br);
217 if ( global_buffer_ring == br )
218 global_buffer_ring = 0;
218} 219}
219 220
220 221
221 222
222/** Like strdup, but the buffer is on the ring. */ 223/** Like strdup, but the buffer is on the ring. */
223char* 224char*
224icalmemory_tmp_copy(const char* str) 225icalmemory_tmp_copy(const char* str)
225{ 226{
226 char* b = icalmemory_tmp_buffer(strlen(str)+1); 227 char* b = icalmemory_tmp_buffer(strlen(str)+1);
227 228
228 strcpy(b,str); 229 strcpy(b,str);
229 230
230 return b; 231 return b;
231} 232}
232 233
233 234
234char* icalmemory_strdup(const char *s) 235char* icalmemory_strdup(const char *s)
235{ 236{
236 return strdup(s); 237 return strdup(s);
237} 238}
238 239
239void 240void
240icalmemory_free_tmp_buffer (void* buf) 241icalmemory_free_tmp_buffer (void* buf)
241{ 242{
242 if(buf == 0) 243 if(buf == 0)
243 { 244 {
244 return; 245 return;
245 } 246 }
246 247
247 free(buf); 248 free(buf);
248} 249}
249 250
250 251
251/* 252/*
252 * These buffer routines create memory the old fashioned way -- so the 253 * These buffer routines create memory the old fashioned way -- so the
253 * caller will have to deallocate the new memory 254 * caller will have to deallocate the new memory
254 */ 255 */
255 256
256void* icalmemory_new_buffer(size_t size) 257void* icalmemory_new_buffer(size_t size)
257{ 258{
258 void *b = malloc(size); 259 void *b = malloc(size);
259 260
260 if( b == 0){ 261 if( b == 0){
261 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 262 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
262 return 0; 263 return 0;
263 } 264 }
264 265
265 memset(b,0,size); 266 memset(b,0,size);
266 267
267 return b; 268 return b;
268} 269}
269 270
270void* icalmemory_resize_buffer(void* buf, size_t size) 271void* icalmemory_resize_buffer(void* buf, size_t size)
271{ 272{
272 void *b = realloc(buf, size); 273 void *b = realloc(buf, size);
273 274
274 if( b == 0){ 275 if( b == 0){
275 icalerror_set_errno(ICAL_NEWFAILED_ERROR); 276 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
276 return 0; 277 return 0;
277 } 278 }
278 279
279 return b; 280 return b;
280} 281}
281 282
282void icalmemory_free_buffer(void* buf) 283void icalmemory_free_buffer(void* buf)
283{ 284{
284 free(buf); 285 free(buf);
285} 286}
286 287
287void 288void
288icalmemory_append_string(char** buf, char** pos, size_t* buf_size, 289icalmemory_append_string(char** buf, char** pos, size_t* buf_size,
289 const char* string) 290 const char* string)
290{ 291{
291 char *new_buf; 292 char *new_buf;
292 char *new_pos; 293 char *new_pos;
293 294
294 size_t data_length, final_length, string_length; 295 size_t data_length, final_length, string_length;
295 296
296#ifndef ICAL_NO_INTERNAL_DEBUG 297#ifndef ICAL_NO_INTERNAL_DEBUG
297 icalerror_check_arg_rv( (buf!=0),"buf"); 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( (pos!=0),"pos"); 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( (buf_size!=0),"buf_size"); 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( (string!=0),"string"); 304 icalerror_check_arg_rv( (string!=0),"string");
304#endif 305#endif
305 306
306 string_length = strlen(string); 307 string_length = strlen(string);
307 data_length = (size_t)*pos - (size_t)*buf; 308 data_length = (size_t)*pos - (size_t)*buf;
308 final_length = data_length + string_length; 309 final_length = data_length + string_length;
309 310
310 if ( final_length >= (size_t) *buf_size) { 311 if ( final_length >= (size_t) *buf_size) {
311 312
312 313
313 *buf_size = (*buf_size) * 2 + final_length; 314 *buf_size = (*buf_size) * 2 + final_length;