restore freeing of threadstorage objects without custom cleanup functions
[asterisk/asterisk.git] / include / asterisk / threadstorage.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2006, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file threadstorage.h
21  * \author Russell Bryant <russell@digium.com>
22  *
23  * \brief Definitions to aid in the use of thread local storage
24 */
25
26 #ifndef ASTERISK_THREADSTORAGE_H
27 #define ASTERISK_THREADSTORAGE_H
28
29 #include <pthread.h>
30
31 #include "asterisk/utils.h"
32 #include "asterisk/inline_api.h"
33
34 /*!
35  * \brief data for a thread locally stored variable
36  */
37 struct ast_threadstorage {
38         /*! Ensure that the key is only initialized by one thread */
39         pthread_once_t once;
40         /*! The key used to retrieve this thread's data */
41         pthread_key_t key;
42         /*! The function that initializes the key */
43         void (*key_init)(void);
44         /*! Custom initialization function specific to the object */
45         int (*custom_init)(void *);
46 };
47
48 /*!
49  * \brief Define a thread storage variable
50  *
51  * \arg name The name of the thread storage object
52  *
53  * This macro would be used to declare an instance of thread storage in a file.
54  *
55  * Example usage:
56  * \code
57  * AST_THREADSTORAGE(my_buf);
58  * \endcode
59  */
60 #define AST_THREADSTORAGE(name) \
61         AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free) 
62
63 /*!
64  * \brief Define a thread storage variable, with custom initialization and cleanup
65  *
66  * \arg name The name of the thread storage object
67  * \arg init This is a custom function that will be called after each thread specific
68  *           object is allocated, with the allocated block of memory passed
69  *           as the argument.
70  * \arg cleanup This is a custom function that will be called instead of ast_free
71  *              when the thread goes away.  Note that if this is used, it *MUST*
72  *              call free on the allocated memory.
73  *
74  * Example usage:
75  * \code
76  * AST_THREADSTORAGE(my_buf, my_init, my_cleanup);
77  * \endcode
78  */
79 #define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
80 static void init_##name(void);                            \
81 static struct ast_threadstorage name = {                  \
82         .once = PTHREAD_ONCE_INIT,                        \
83         .key_init = init_##name,                          \
84         .custom_init = c_init,                            \
85 };                                                        \
86 static void init_##name(void)                             \
87 {                                                         \
88         pthread_key_create(&(name).key, c_cleanup);       \
89 }
90
91 /*!
92  * \brief Retrieve thread storage
93  *
94  * \arg ts This is a pointer to the thread storage structure declared by using
95  *      the AST_THREADSTORAGE macro.  If declared with 
96  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
97  *      (&my_buf).
98  * \arg init_size This is the amount of space to be allocated the first time
99  *      this thread requests its data. Thus, this should be the size that the
100  *      code accessing this thread storage is assuming the size to be.
101  *
102  * \return This function will return the thread local storage associated with
103  *         the thread storage management variable passed as the first argument.
104  *         The result will be NULL in the case of a memory allocation error.
105  *
106  * Example usage:
107  * \code
108  * AST_THREADSTORAGE(my_buf, my_buf_init);
109  * #define MY_BUF_SIZE   128
110  * ...
111  * void my_func(const char *fmt, ...)
112  * {
113  *      void *buf;
114  *
115  *      if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE)))
116  *           return;
117  *      ...
118  * }
119  * \endcode
120  */
121 AST_INLINE_API(
122 void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
123 {
124         void *buf;
125
126         pthread_once(&ts->once, ts->key_init);
127         if (!(buf = pthread_getspecific(ts->key))) {
128                 if (!(buf = ast_calloc(1, init_size)))
129                         return NULL;
130                 if (ts->custom_init && ts->custom_init(buf)) {
131                         free(buf);
132                         return NULL;
133                 }
134                 pthread_setspecific(ts->key, buf);
135         }
136
137         return buf;
138 }
139 )
140
141 void __ast_threadstorage_cleanup(void *);
142
143 /*!
144  * \brief A dynamic length string
145  */
146 struct ast_dynamic_str {
147         /* The current maximum length of the string */
148         size_t len;
149         /* The string buffer */
150         char str[0];
151 };
152
153 /*!
154  * \brief Create a dynamic length string
155  *
156  * \arg init_len This is the initial length of the string buffer
157  *
158  * \return This function returns a pointer to the dynamic string length.  The
159  *         result will be NULL in the case of a memory allocation error.
160  *
161  * /note The result of this function is dynamically allocated memory, and must
162  *       be free()'d after it is no longer needed.
163  */
164 AST_INLINE_API(
165 struct ast_dynamic_str * attribute_malloc ast_dynamic_str_create(size_t init_len),
166 {
167         struct ast_dynamic_str *buf;
168
169         if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))
170                 return NULL;
171         
172         buf->len = init_len;
173
174         return buf;
175 }
176 )
177
178 /*!
179  * \brief Retrieve a thread locally stored dynamic string
180  *
181  * \arg ts This is a pointer to the thread storage structure declared by using
182  *      the AST_THREADSTORAGE macro.  If declared with 
183  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
184  *      (&my_buf).
185  * \arg init_len This is the initial length of the thread's dynamic string. The
186  *      current length may be bigger if previous operations in this thread have
187  *      caused it to increase.
188  *
189  * \return This function will return the thread locally storaged dynamic string
190  *         associated with the thread storage management variable passed as the
191  *         first argument.
192  *         The result will be NULL in the case of a memory allocation error.
193  *
194  * Example usage:
195  * \code
196  * AST_THREADSTORAGE(my_str, my_str_init);
197  * #define MY_STR_INIT_SIZE   128
198  * ...
199  * void my_func(const char *fmt, ...)
200  * {
201  *      struct ast_dynamic_str *buf;
202  *
203  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
204  *           return;
205  *      ...
206  * }
207  * \endcode
208  */
209 AST_INLINE_API(
210 struct ast_dynamic_str *ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
211         size_t init_len),
212 {
213         struct ast_dynamic_str *buf;
214
215         if (!(buf = ast_threadstorage_get(ts, sizeof(*buf) + init_len)))
216                 return NULL;
217         
218         if (!buf->len)
219                 buf->len = init_len;
220
221         return buf;
222 }
223 )
224
225 /*!
226  * \brief Error codes from ast_dynamic_str_thread_build_va()
227  */
228 enum {
229         /*! An error has occured and the contents of the dynamic string
230          *  are undefined */
231         AST_DYNSTR_BUILD_FAILED = -1,
232         /*! The buffer size for the dynamic string had to be increased, and
233          *  ast_dynamic_str_thread_build_va() needs to be called again after
234          *  a va_end() and va_start().
235          */
236         AST_DYNSTR_BUILD_RETRY = -2
237 };
238
239 /*!
240  * \brief Set a thread locally stored dynamic string from a va_list
241  *
242  * \arg buf This is the address of a pointer to an ast_dynamic_str which should
243  *      have been retrieved using ast_dynamic_str_thread_get.  It will need to
244  *      be updated in the case that the buffer has to be reallocated to
245  *      accomodate a longer string than what it currently has space for.
246  * \arg max_len This is the maximum length to allow the string buffer to grow
247  *      to.  If this is set to 0, then there is no maximum length.
248  * \arg ts This is a pointer to the thread storage structure declared by using
249  *      the AST_THREADSTORAGE macro.  If declared with 
250  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
251  *      (&my_buf).
252  * \arg fmt This is the format string (printf style)
253  * \arg ap This is the va_list
254  *
255  * \return The return value of this function is the same as that of the printf
256  *         family of functions.
257  *
258  * Example usage:
259  * \code
260  * AST_THREADSTORAGE(my_str, my_str_init);
261  * #define MY_STR_INIT_SIZE   128
262  * ...
263  * void my_func(const char *fmt, ...)
264  * {
265  *      struct ast_dynamic_str *buf;
266  *      va_list ap;
267  *
268  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
269  *           return;
270  *      ...
271  *      va_start(fmt, ap);
272  *      ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
273  *      va_end(ap);
274  * 
275  *      printf("This is the string we just built: %s\n", buf->str);
276  *      ...
277  * }
278  * \endcode
279  */
280 #define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap)                 \
281         ({                                                                       \
282                 int __res;                                                       \
283                 while ((__res = ast_dynamic_str_thread_build_va(buf, max_len,    \
284                         ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {            \
285                         va_end(ap);                                              \
286                         va_start(ap, fmt);                                       \
287                 }                                                                \
288                 (__res);                                                         \
289         })
290
291 /*!
292  * \brief Append to a thread local dynamic string using a va_list
293  *
294  * The arguments, return values, and usage of this are the same as those for
295  * ast_dynamic_str_thread_set_va().  However, instead of setting a new value
296  * for the string, this will append to the current value.
297  */
298 #define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap)              \
299         ({                                                                       \
300                 int __res;                                                       \
301                 while ((__res = ast_dynamic_str_thread_build_va(buf, max_len,    \
302                         ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {            \
303                         va_end(ap);                                              \
304                         va_start(ap, fmt);                                       \
305                 }                                                                \
306                 (__res);                                                         \
307         })
308
309 /*!
310  * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
311  *
312  * The arguments to this function are the same as those described for
313  * ast_dynamic_str_thread_set_va except for an addition argument, append.
314  * If append is non-zero, this will append to the current string instead of
315  * writing over it.
316  */
317 int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
318         struct ast_threadstorage *ts, int append, const char *fmt, va_list ap);
319
320 /*!
321  * \brief Set a thread locally stored dynamic string using variable arguments
322  *
323  * \arg buf This is the address of a pointer to an ast_dynamic_str which should
324  *      have been retrieved using ast_dynamic_str_thread_get.  It will need to
325  *      be updated in the case that the buffer has to be reallocated to
326  *      accomodate a longer string than what it currently has space for.
327  * \arg max_len This is the maximum length to allow the string buffer to grow
328  *      to.  If this is set to 0, then there is no maximum length.
329  * \arg ts This is a pointer to the thread storage structure declared by using
330  *      the AST_THREADSTORAGE macro.  If declared with 
331  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
332  *      (&my_buf).
333  * \arg fmt This is the format string (printf style)
334  *
335  * \return The return value of this function is the same as that of the printf
336  *         family of functions.
337  *
338  * Example usage:
339  * \code
340  * AST_THREADSTORAGE(my_str, my_str_init);
341  * #define MY_STR_INIT_SIZE   128
342  * ...
343  * void my_func(int arg1, int arg2)
344  * {
345  *      struct ast_dynamic_str *buf;
346  *      va_list ap;
347  *
348  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
349  *           return;
350  *      ...
351  *      ast_dynamic_str_thread_set(&buf, 0, &my_str, "arg1: %d  arg2: %d\n",
352  *           arg1, arg2);
353  * 
354  *      printf("This is the string we just built: %s\n", buf->str);
355  *      ...
356  * }
357  * \endcode
358  */
359 AST_INLINE_API(
360 int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_set(
361         struct ast_dynamic_str **buf, size_t max_len, 
362         struct ast_threadstorage *ts, const char *fmt, ...),
363 {
364         int res;
365         va_list ap;
366
367         va_start(ap, fmt);
368         res = ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap);
369         va_end(ap);
370
371         return res;
372 }
373 )
374
375 /*!
376  * \brief Append to a thread local dynamic string
377  *
378  * The arguments, return values, and usage of this function are the same as
379  * ast_dynamic_str_thread_set().  However, instead of setting a new value for
380  * the string, this function appends to the current value.
381  */
382 AST_INLINE_API(
383 int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_append(
384         struct ast_dynamic_str **buf, size_t max_len, 
385         struct ast_threadstorage *ts, const char *fmt, ...),
386 {
387         int res;
388         va_list ap;
389
390         va_start(ap, fmt);
391         res = ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap);
392         va_end(ap);
393
394         return res;
395 }
396 )
397
398 /*!
399  * \brief Set a dynamic string
400  *
401  * \arg buf This is the address of a pointer to an ast_dynamic_str.  It will
402  *      need to be updated in the case that the buffer has to be reallocated to
403  *      accomodate a longer string than what it currently has space for.
404  * \arg max_len This is the maximum length to allow the string buffer to grow
405  *      to.  If this is set to 0, then there is no maximum length.
406  *
407  * \return The return value of this function is the same as that of the printf
408  *         family of functions.
409  */
410 AST_INLINE_API(
411 int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_set(
412         struct ast_dynamic_str **buf, size_t max_len,
413         const char *fmt, ...),
414 {
415         int res;
416         va_list ap;
417         
418         va_start(ap, fmt);
419         res = ast_dynamic_str_thread_set_va(buf, max_len, NULL, fmt, ap);
420         va_end(ap);
421
422         return res;
423 }
424 )
425
426 /*!
427  * \brief Append to a dynatic string
428  *
429  * The arguments, return values, and usage of this function are the same as
430  * ast_dynamic_str_set().  However, this function appends to the string instead
431  * of setting a new value.
432  */
433 AST_INLINE_API(
434 int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_append(
435         struct ast_dynamic_str **buf, size_t max_len,
436         const char *fmt, ...),
437 {
438         int res;
439         va_list ap;
440         
441         va_start(ap, fmt);
442         res = ast_dynamic_str_thread_append_va(buf, max_len, NULL, fmt, ap);
443         va_end(ap);
444
445         return res;
446 }
447 )
448
449 #endif /* ASTERISK_THREADSTORAGE_H */