small documentation improvements.
[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  * \brief Definitions to aid in the use of thread local storage
23  *
24  * \arg \ref AstThreadStorage
25  */
26
27 /*!
28  * \page AstThreadStorage The Asterisk Thread Storage API
29  *
30  *
31  * The POSIX threads (pthreads) API provides the ability to define thread
32  * specific data.  The functions and structures defined here are intended
33  * to centralize the code that is commonly used when using thread local
34  * storage.
35  *
36  * The motivation for using this code in Asterisk is for situations where
37  * storing data on a thread-specific basis can provide some amount of
38  * performance benefit.  For example, there are some call types in Asterisk
39  * where ast_frame structures must be allocated very rapidly (easily 50, 100,
40  * 200 times a second).  Instead of doing the equivalent of that many calls
41  * to malloc() and free() per second, thread local storage is used to keep a
42  * list of unused frame structures so that they can be continuously reused.
43  *
44  * - \ref threadstorage.h
45  */
46
47 #ifndef ASTERISK_THREADSTORAGE_H
48 #define ASTERISK_THREADSTORAGE_H
49
50 #include <pthread.h>
51
52 #include "asterisk/utils.h"
53 #include "asterisk/inline_api.h"
54
55 /*!
56  * \brief data for a thread locally stored variable
57  */
58 struct ast_threadstorage {
59         /*! Ensure that the key is only initialized by one thread */
60         pthread_once_t once;
61         /*! The key used to retrieve this thread's data */
62         pthread_key_t key;
63         /*! The function that initializes the key */
64         void (*key_init)(void);
65         /*! Custom initialization function specific to the object */
66         int (*custom_init)(void *);
67 };
68
69 /*!
70  * \brief Define a thread storage variable
71  *
72  * \arg name The name of the thread storage object
73  *
74  * This macro would be used to declare an instance of thread storage in a file.
75  *
76  * Example usage:
77  * \code
78  * AST_THREADSTORAGE(my_buf);
79  * \endcode
80  */
81 #define AST_THREADSTORAGE(name) \
82         AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free) 
83
84 /*!
85  * \brief Define a thread storage variable, with custom initialization and cleanup
86  *
87  * \arg name The name of the thread storage object
88  * \arg init This is a custom function that will be called after each thread specific
89  *           object is allocated, with the allocated block of memory passed
90  *           as the argument.
91  * \arg cleanup This is a custom function that will be called instead of ast_free
92  *              when the thread goes away.  Note that if this is used, it *MUST*
93  *              call free on the allocated memory.
94  *
95  * Example usage:
96  * \code
97  * AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
98  * \endcode
99  */
100 #define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
101 static void init_##name(void);                            \
102 static struct ast_threadstorage name = {                  \
103         .once = PTHREAD_ONCE_INIT,                        \
104         .key_init = init_##name,                          \
105         .custom_init = c_init,                            \
106 };                                                        \
107 static void init_##name(void)                             \
108 {                                                         \
109         pthread_key_create(&(name).key, c_cleanup);       \
110 }
111
112 /*!
113  * \brief Retrieve thread storage
114  *
115  * \arg ts This is a pointer to the thread storage structure declared by using
116  *      the AST_THREADSTORAGE macro.  If declared with 
117  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
118  *      (&my_buf).
119  * \arg init_size This is the amount of space to be allocated the first time
120  *      this thread requests its data. Thus, this should be the size that the
121  *      code accessing this thread storage is assuming the size to be.
122  *
123  * \return This function will return the thread local storage associated with
124  *         the thread storage management variable passed as the first argument.
125  *         The result will be NULL in the case of a memory allocation error.
126  *
127  * Example usage:
128  * \code
129  * AST_THREADSTORAGE(my_buf, my_buf_init);
130  * #define MY_BUF_SIZE   128
131  * ...
132  * void my_func(const char *fmt, ...)
133  * {
134  *      void *buf;
135  *
136  *      if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE)))
137  *           return;
138  *      ...
139  * }
140  * \endcode
141  */
142 AST_INLINE_API(
143 void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
144 {
145         void *buf;
146
147         pthread_once(&ts->once, ts->key_init);
148         if (!(buf = pthread_getspecific(ts->key))) {
149                 if (!(buf = ast_calloc(1, init_size)))
150                         return NULL;
151                 if (ts->custom_init && ts->custom_init(buf)) {
152                         free(buf);
153                         return NULL;
154                 }
155                 pthread_setspecific(ts->key, buf);
156         }
157
158         return buf;
159 }
160 )
161
162 void __ast_threadstorage_cleanup(void *);
163
164 /*!
165  * A dynamic length string. This is just a C string prefixed by a length
166  * field. len reflects the actual space allocated, while the string is
167  * NUL-terminated as a regular C string.
168  * One should never declare a variable with this type, but only a pointer
169  * to it, and use ast_dynamic_str_create() to initialize it.
170  */
171 struct ast_dynamic_str {
172         size_t len;     /*!< The current maximum length of the string */
173         char str[0];    /*!< The string buffer */
174 };
175
176 /*!
177  * \brief Create a dynamic length string
178  *
179  * \arg init_len This is the initial length of the string buffer
180  *
181  * \return This function returns a pointer to the dynamic string length.  The
182  *         result will be NULL in the case of a memory allocation error.
183  *
184  * \note The result of this function is dynamically allocated memory, and must
185  *       be free()'d after it is no longer needed.
186  */
187 AST_INLINE_API(
188 struct ast_dynamic_str * attribute_malloc ast_dynamic_str_create(size_t init_len),
189 {
190         struct ast_dynamic_str *buf;
191
192         if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))
193                 return NULL;
194         
195         buf->len = init_len;
196
197         return buf;
198 }
199 )
200
201 /*!
202  * \brief Retrieve a thread locally stored dynamic string
203  *
204  * \arg ts This is a pointer to the thread storage structure declared by using
205  *      the AST_THREADSTORAGE macro.  If declared with 
206  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
207  *      (&my_buf).
208  * \arg init_len This is the initial length of the thread's dynamic string. The
209  *      current length may be bigger if previous operations in this thread have
210  *      caused it to increase.
211  *
212  * \return This function will return the thread locally stored dynamic string
213  *         associated with the thread storage management variable passed as the
214  *         first argument.
215  *         The result will be NULL in the case of a memory allocation error.
216  *
217  * Example usage:
218  * \code
219  * AST_THREADSTORAGE(my_str, my_str_init);
220  * #define MY_STR_INIT_SIZE   128
221  * ...
222  * void my_func(const char *fmt, ...)
223  * {
224  *      struct ast_dynamic_str *buf;
225  *
226  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
227  *           return;
228  *      ...
229  * }
230  * \endcode
231  */
232 AST_INLINE_API(
233 struct ast_dynamic_str *ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
234         size_t init_len),
235 {
236         struct ast_dynamic_str *buf;
237
238         if (!(buf = ast_threadstorage_get(ts, sizeof(*buf) + init_len)))
239                 return NULL;
240         
241         if (!buf->len)
242                 buf->len = init_len;
243
244         return buf;
245 }
246 )
247
248 /*!
249  * \brief Error codes from ast_dynamic_str_thread_build_va()
250  */
251 enum {
252         /*! An error has occured and the contents of the dynamic string
253          *  are undefined */
254         AST_DYNSTR_BUILD_FAILED = -1,
255         /*! The buffer size for the dynamic string had to be increased, and
256          *  ast_dynamic_str_thread_build_va() needs to be called again after
257          *  a va_end() and va_start().
258          */
259         AST_DYNSTR_BUILD_RETRY = -2
260 };
261
262 /*!
263  * \brief Set a thread locally stored dynamic string from a va_list
264  *
265  * \arg buf This is the address of a pointer to an ast_dynamic_str which should
266  *      have been retrieved using ast_dynamic_str_thread_get.  It will need to
267  *      be updated in the case that the buffer has to be reallocated to
268  *      accommodate a longer string than what it currently has space for.
269  * \arg max_len This is the maximum length to allow the string buffer to grow
270  *      to.  If this is set to 0, then there is no maximum length.
271  * \arg ts This is a pointer to the thread storage structure declared by using
272  *      the AST_THREADSTORAGE macro.  If declared with 
273  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
274  *      (&my_buf).
275  * \arg fmt This is the format string (printf style)
276  * \arg ap This is the va_list
277  *
278  * \return The return value of this function is the same as that of the printf
279  *         family of functions.
280  *
281  * Example usage:
282  * \code
283  * AST_THREADSTORAGE(my_str, my_str_init);
284  * #define MY_STR_INIT_SIZE   128
285  * ...
286  * void my_func(const char *fmt, ...)
287  * {
288  *      struct ast_dynamic_str *buf;
289  *      va_list ap;
290  *
291  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
292  *           return;
293  *      ...
294  *      va_start(fmt, ap);
295  *      ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
296  *      va_end(ap);
297  * 
298  *      printf("This is the string we just built: %s\n", buf->str);
299  *      ...
300  * }
301  * \endcode
302  */
303 #define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap)                 \
304         ({                                                                       \
305                 int __res;                                                       \
306                 while ((__res = ast_dynamic_str_thread_build_va(buf, max_len,    \
307                         ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {            \
308                         va_end(ap);                                              \
309                         va_start(ap, fmt);                                       \
310                 }                                                                \
311                 (__res);                                                         \
312         })
313
314 /*!
315  * \brief Append to a thread local dynamic string using a va_list
316  *
317  * The arguments, return values, and usage of this are the same as those for
318  * ast_dynamic_str_thread_set_va().  However, instead of setting a new value
319  * for the string, this will append to the current value.
320  */
321 #define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap)              \
322         ({                                                                       \
323                 int __res;                                                       \
324                 while ((__res = ast_dynamic_str_thread_build_va(buf, max_len,    \
325                         ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {            \
326                         va_end(ap);                                              \
327                         va_start(ap, fmt);                                       \
328                 }                                                                \
329                 (__res);                                                         \
330         })
331
332 /*!
333  * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
334  *
335  * The arguments to this function are the same as those described for
336  * ast_dynamic_str_thread_set_va except for an addition argument, append.
337  * If append is non-zero, this will append to the current string instead of
338  * writing over it.
339  *
340  * In the case that this function is called and the buffer was not large enough
341  * to hold the result, the partial write will be truncated, and the result
342  * AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size
343  * was increased, and the function should be called a second time.
344  *
345  * A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error.
346  *
347  * A return value greater than or equal to zero indicates the number of
348  * characters that have been written, not including the terminating '\0'.
349  * In the append case, this only includes the number of characters appended.
350  *
351  * \note This function should never need to be called directly.  It should
352  *       through calling one of the other functions or macros defined in this
353  *       file.
354  */
355 int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
356         struct ast_threadstorage *ts, int append, const char *fmt, va_list ap);
357
358 /*!
359  * \brief Set a thread locally stored dynamic string using variable arguments
360  *
361  * \arg buf This is the address of a pointer to an ast_dynamic_str which should
362  *      have been retrieved using ast_dynamic_str_thread_get.  It will need to
363  *      be updated in the case that the buffer has to be reallocated to
364  *      accomodate a longer string than what it currently has space for.
365  * \arg max_len This is the maximum length to allow the string buffer to grow
366  *      to.  If this is set to 0, then there is no maximum length.
367  * \arg ts This is a pointer to the thread storage structure declared by using
368  *      the AST_THREADSTORAGE macro.  If declared with 
369  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 
370  *      (&my_buf).
371  * \arg fmt This is the format string (printf style)
372  *
373  * \return The return value of this function is the same as that of the printf
374  *         family of functions.
375  *
376  * Example usage:
377  * \code
378  * AST_THREADSTORAGE(my_str, my_str_init);
379  * #define MY_STR_INIT_SIZE   128
380  * ...
381  * void my_func(int arg1, int arg2)
382  * {
383  *      struct ast_dynamic_str *buf;
384  *      va_list ap;
385  *
386  *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
387  *           return;
388  *      ...
389  *      ast_dynamic_str_thread_set(&buf, 0, &my_str, "arg1: %d  arg2: %d\n",
390  *           arg1, arg2);
391  * 
392  *      printf("This is the string we just built: %s\n", buf->str);
393  *      ...
394  * }
395  * \endcode
396  */
397 AST_INLINE_API(
398 int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_set(
399         struct ast_dynamic_str **buf, size_t max_len, 
400         struct ast_threadstorage *ts, const char *fmt, ...),
401 {
402         int res;
403         va_list ap;
404
405         va_start(ap, fmt);
406         res = ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap);
407         va_end(ap);
408
409         return res;
410 }
411 )
412
413 /*!
414  * \brief Append to a thread local dynamic string
415  *
416  * The arguments, return values, and usage of this function are the same as
417  * ast_dynamic_str_thread_set().  However, instead of setting a new value for
418  * the string, this function appends to the current value.
419  */
420 AST_INLINE_API(
421 int __attribute__ ((format (printf, 4, 5))) ast_dynamic_str_thread_append(
422         struct ast_dynamic_str **buf, size_t max_len, 
423         struct ast_threadstorage *ts, const char *fmt, ...),
424 {
425         int res;
426         va_list ap;
427
428         va_start(ap, fmt);
429         res = ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap);
430         va_end(ap);
431
432         return res;
433 }
434 )
435
436 /*!
437  * \brief Set a dynamic string
438  *
439  * \arg buf This is the address of a pointer to an ast_dynamic_str.  It will
440  *      need to be updated in the case that the buffer has to be reallocated to
441  *      accommodate a longer string than what it currently has space for.
442  * \arg max_len This is the maximum length to allow the string buffer to grow
443  *      to.  If this is set to 0, then there is no maximum length.
444  *
445  * \return The return value of this function is the same as that of the printf
446  *         family of functions.
447  */
448 AST_INLINE_API(
449 int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_set(
450         struct ast_dynamic_str **buf, size_t max_len,
451         const char *fmt, ...),
452 {
453         int res;
454         va_list ap;
455         
456         va_start(ap, fmt);
457         res = ast_dynamic_str_thread_set_va(buf, max_len, NULL, fmt, ap);
458         va_end(ap);
459
460         return res;
461 }
462 )
463
464 /*!
465  * \brief Append to a dynamic string
466  *
467  * The arguments, return values, and usage of this function are the same as
468  * ast_dynamic_str_set().  However, this function appends to the string instead
469  * of setting a new value.
470  */
471 AST_INLINE_API(
472 int __attribute__ ((format (printf, 3, 4))) ast_dynamic_str_append(
473         struct ast_dynamic_str **buf, size_t max_len,
474         const char *fmt, ...),
475 {
476         int res;
477         va_list ap;
478         
479         va_start(ap, fmt);
480         res = ast_dynamic_str_thread_append_va(buf, max_len, NULL, fmt, ap);
481         va_end(ap);
482
483         return res;
484 }
485 )
486
487 #endif /* ASTERISK_THREADSTORAGE_H */