Adds DAHDI support alongside Zaptel. DAHDI usage favored, but all Zap stuff should...
[asterisk-bristuff.git] / include / asterisk / astobj.h
blobdd6207ff8b787d782646f04c771c56262f7bebbc
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
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.
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.
20 * Object Model for Asterisk
23 #ifndef _ASTERISK_ASTOBJ_H
24 #define _ASTERISK_ASTOBJ_H
26 #include <string.h>
28 #include "asterisk/lock.h"
29 #include "asterisk/compiler.h"
31 /*! \file
32 * \brief A set of macros implementing objects and containers.
33 * Macros are used for maximum performance, to support multiple inheritance,
34 * and to be easily integrated into existing structures without additional
35 * malloc calls, etc.
37 * These macros expect to operate on two different object types, ASTOBJs and
38 * ASTOBJ_CONTAINERs. These are not actual types, as any struct can be
39 * converted into an ASTOBJ compatible object or container using the supplied
40 * macros.
42 * <b>Sample Usage:</b>
43 * \code
44 * struct sample_object {
45 * ASTOBJ_COMPONENTS(struct sample_object);
46 * };
48 * struct sample_container {
49 * ASTOBJ_CONTAINER_COMPONENTS(struct sample_object);
50 * } super_container;
52 * void sample_object_destroy(struct sample_object *obj)
53 * {
54 * free(obj);
55 * }
57 * int init_stuff()
58 * {
59 * struct sample_object *obj1;
60 * struct sample_object *found_obj;
62 * obj1 = malloc(sizeof(struct sample_object));
64 * ASTOBJ_CONTAINER_INIT(&super_container);
66 * ASTOBJ_INIT(obj1);
67 * ASTOBJ_WRLOCK(obj1);
68 * ast_copy_string(obj1->name, "obj1", sizeof(obj1->name));
69 * ASTOBJ_UNLOCK(obj1);
71 * ASTOBJ_CONTAINER_LINK(&super_container, obj1);
73 * found_obj = ASTOBJ_CONTAINER_FIND(&super_container, "obj1");
75 * if(found_obj) {
76 * printf("Found object: %s", found_obj->name);
77 * ASTOBJ_UNREF(found_obj,sample_object_destroy);
78 * }
80 * ASTOBJ_CONTAINER_DESTROYALL(&super_container,sample_object_destroy);
81 * ASTOBJ_CONTAINER_DESTROY(&super_container);
83 * return 0;
84 * }
85 * \endcode
88 #if defined(__cplusplus) || defined(c_plusplus)
89 extern "C" {
90 #endif
92 #define ASTOBJ_DEFAULT_NAMELEN 80
93 #define ASTOBJ_DEFAULT_BUCKETS 256
94 #define ASTOBJ_DEFAULT_HASH ast_strhash
96 #define ASTOBJ_FLAG_MARKED (1 << 0) /* Object has been marked for future operation */
98 /* C++ is simply a syntactic crutch for those who cannot think for themselves
99 in an object oriented way. */
101 /*! \brief Lock an ASTOBJ for reading.
103 #define ASTOBJ_RDLOCK(object) ast_mutex_lock(&(object)->_lock)
105 /*! \brief Lock an ASTOBJ for writing.
107 #define ASTOBJ_WRLOCK(object) ast_mutex_lock(&(object)->_lock)
109 /*! \brief Unlock a locked object. */
110 #define ASTOBJ_UNLOCK(object) ast_mutex_unlock(&(object)->_lock)
112 #ifdef ASTOBJ_CONTAINER_HASHMODEL
113 #define __ASTOBJ_HASH(type,hashes) \
114 type *next[hashes]
115 #else
116 #define __ASTOBJ_HASH(type,hashes) \
117 type *next[1]
118 #endif
120 /*! \brief Add ASTOBJ components to a struct (without locking support).
122 * \param type The datatype of the object.
123 * \param namelen The length to make the name char array.
124 * \param hashes The number of containers the object can be present in.
126 * This macro adds components to a struct to make it an ASTOBJ. This macro
127 * differs from ASTOBJ_COMPONENTS_FULL in that it does not create a mutex for
128 * locking.
130 * <b>Sample Usage:</b>
131 * \code
132 * struct sample_struct {
133 * ASTOBJ_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
134 * };
135 * \endcode
137 #define ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes) \
138 char name[namelen]; \
139 unsigned int refcount; \
140 unsigned int objflags; \
141 __ASTOBJ_HASH(type,hashes)
143 /*! \brief Add ASTOBJ components to a struct (without locking support).
145 * \param type The datatype of the object.
147 * This macro works like #ASTOBJ_COMPONENTS_NOLOCK_FULL() except it only accepts a
148 * type and uses default values for namelen and hashes.
150 * <b>Sample Usage:</b>
151 * \code
152 * struct sample_struct_componets {
153 * ASTOBJ_COMPONENTS_NOLOCK(struct sample_struct);
154 * };
155 * \endcode
157 #define ASTOBJ_COMPONENTS_NOLOCK(type) \
158 ASTOBJ_COMPONENTS_NOLOCK_FULL(type,ASTOBJ_DEFAULT_NAMELEN,1)
160 /*! \brief Add ASTOBJ components to a struct (with locking support).
162 * \param type The datatype of the object.
164 * This macro works like #ASTOBJ_COMPONENTS_NOLOCK() except it includes locking
165 * support.
167 * <b>Sample Usage:</b>
168 * \code
169 * struct sample_struct {
170 * ASTOBJ_COMPONENTS(struct sample_struct);
171 * };
172 * \endcode
174 #define ASTOBJ_COMPONENTS(type) \
175 ASTOBJ_COMPONENTS_NOLOCK(type); \
176 ast_mutex_t _lock;
178 /*! \brief Add ASTOBJ components to a struct (with locking support).
180 * \param type The datatype of the object.
181 * \param namelen The length to make the name char array.
182 * \param hashes The number of containers the object can be present in.
184 * This macro adds components to a struct to make it an ASTOBJ and includes
185 * support for locking.
187 * <b>Sample Usage:</b>
188 * \code
189 * struct sample_struct {
190 * ASTOBJ_COMPONENTS_FULL(struct sample_struct,1,1);
191 * };
192 * \endcode
194 #define ASTOBJ_COMPONENTS_FULL(type,namelen,hashes) \
195 ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes); \
196 ast_mutex_t _lock;
198 /*! \brief Increment an object reference count.
199 * \param object A pointer to the object to operate on.
200 * \return The object.
202 #define ASTOBJ_REF(object) \
203 ({ \
204 ASTOBJ_WRLOCK(object); \
205 (object)->refcount++; \
206 ASTOBJ_UNLOCK(object); \
207 (object); \
210 /*! \brief Decrement the reference count on an object.
212 * \param object A pointer the object to operate on.
213 * \param destructor The destructor to call if the object is no longer referenced. It will be passed the pointer as an argument.
215 * This macro unreferences an object and calls the specfied destructor if the
216 * object is no longer referenced. The destructor should free the object if it
217 * was dynamically allocated.
219 #define ASTOBJ_UNREF(object,destructor) \
220 do { \
221 int newcount = 0; \
222 ASTOBJ_WRLOCK(object); \
223 if (__builtin_expect((object)->refcount > 0, 1)) \
224 newcount = --((object)->refcount); \
225 else \
226 ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \
227 ASTOBJ_UNLOCK(object); \
228 if (newcount == 0) { \
229 ast_mutex_destroy(&(object)->_lock); \
230 destructor((object)); \
232 (object) = NULL; \
233 } while(0)
235 /*! \brief Mark an ASTOBJ by adding the #ASTOBJ_FLAG_MARKED flag to its objflags mask.
236 * \param object A pointer to the object to operate on.
238 * This macro "marks" an object. Marked objects can later be unlinked from a container using
239 * #ASTOBJ_CONTAINER_PRUNE_MARKED().
242 #define ASTOBJ_MARK(object) \
243 do { \
244 ASTOBJ_WRLOCK(object); \
245 (object)->objflags |= ASTOBJ_FLAG_MARKED; \
246 ASTOBJ_UNLOCK(object); \
247 } while(0)
249 /*! \brief Unmark an ASTOBJ by subtracting the #ASTOBJ_FLAG_MARKED flag from its objflags mask.
250 * \param object A pointer to the object to operate on.
252 #define ASTOBJ_UNMARK(object) \
253 do { \
254 ASTOBJ_WRLOCK(object); \
255 (object)->objflags &= ~ASTOBJ_FLAG_MARKED; \
256 ASTOBJ_UNLOCK(object); \
257 } while(0)
259 /*! \brief Initialize an object.
260 * \param object A pointer to the object to operate on.
262 * \note This should only be used on objects that support locking (objects
263 * created with #ASTOBJ_COMPONENTS() or #ASTOBJ_COMPONENTS_FULL())
265 #define ASTOBJ_INIT(object) \
266 do { \
267 ast_mutex_init(&(object)->_lock); \
268 object->name[0] = '\0'; \
269 object->refcount = 1; \
270 } while(0)
272 /* Containers for objects -- current implementation is linked lists, but
273 should be able to be converted to hashes relatively easily */
275 /*! \brief Lock an ASTOBJ_CONTAINER for reading.
277 #define ASTOBJ_CONTAINER_RDLOCK(container) ast_mutex_lock(&(container)->_lock)
279 /*! \brief Lock an ASTOBJ_CONTAINER for writing.
281 #define ASTOBJ_CONTAINER_WRLOCK(container) ast_mutex_lock(&(container)->_lock)
283 /*! \brief Unlock an ASTOBJ_CONTAINER. */
284 #define ASTOBJ_CONTAINER_UNLOCK(container) ast_mutex_unlock(&(container)->_lock)
286 #ifdef ASTOBJ_CONTAINER_HASHMODEL
287 #error "Hash model for object containers not yet implemented!"
288 #else
289 /* Linked lists */
291 /*! \brief Create a container for ASTOBJs (without locking support).
293 * \param type The type of objects the container will hold.
294 * \param hashes Currently unused.
295 * \param buckets Currently unused.
297 * This macro is used to create a container for ASTOBJs without locking
298 * support.
300 * <b>Sample Usage:</b>
301 * \code
302 * struct sample_struct_nolock_container {
303 * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
304 * };
305 * \endcode
307 #define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,hashes,buckets) \
308 type *head
310 /*! \brief Initialize a container.
312 * \param container A pointer to the container to initialize.
313 * \param hashes Currently unused.
314 * \param buckets Currently unused.
316 * This macro initializes a container. It should only be used on containers
317 * that support locking.
319 * <b>Sample Usage:</b>
320 * \code
321 * struct sample_struct_container {
322 * ASTOBJ_CONTAINER_COMPONENTS_FULL(struct sample_struct,1,1);
323 * } container;
325 * int func()
327 * ASTOBJ_CONTAINER_INIT_FULL(&container,1,1);
329 * \endcode
331 #define ASTOBJ_CONTAINER_INIT_FULL(container,hashes,buckets) \
332 do { \
333 ast_mutex_init(&(container)->_lock); \
334 } while(0)
336 /*! \brief Destroy a container.
338 * \param container A pointer to the container to destroy.
339 * \param hashes Currently unused.
340 * \param buckets Currently unused.
342 * This macro frees up resources used by a container. It does not operate on
343 * the objects in the container. To unlink the objects from the container use
344 * #ASTOBJ_CONTAINER_DESTROYALL().
346 * \note This macro should only be used on containers with locking support.
348 #define ASTOBJ_CONTAINER_DESTROY_FULL(container,hashes,buckets) \
349 do { \
350 ast_mutex_destroy(&(container)->_lock); \
351 } while(0)
353 /*! \brief Iterate through the objects in a container.
355 * \param container A pointer to the container to traverse.
356 * \param continue A condition to allow the traversal to continue.
357 * \param eval A statement to evaluate in the iteration loop.
359 * This is macro is a little complicated, but it may help to think of it as a
360 * loop. Basically it iterates through the specfied containter as long as the
361 * condition is met. Two variables, iterator and next, are provided for use in
362 * your \p eval statement. See the sample code for an example.
364 * <b>Sample Usage:</b>
365 * \code
366 * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, {
367 * ASTOBJ_RDLOCK(iterator);
368 * printf("Currently iterating over '%s'\n", iterator->name);
369 * ASTOBJ_UNLOCK(iterator);
370 * } );
371 * \endcode
373 * \code
374 * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, sample_func(iterator));
375 * \endcode
377 #define ASTOBJ_CONTAINER_TRAVERSE(container,continue,eval) \
378 do { \
379 typeof((container)->head) iterator; \
380 typeof((container)->head) next; \
381 ASTOBJ_CONTAINER_RDLOCK(container); \
382 next = (container)->head; \
383 while((continue) && (iterator = next)) { \
384 next = iterator->next[0]; \
385 eval; \
387 ASTOBJ_CONTAINER_UNLOCK(container); \
388 } while(0)
390 /*! \brief Find an object in a container.
392 * \param container A pointer to the container to search.
393 * \param namestr The name to search for.
395 * Use this function to find an object with the specfied name in a container.
397 * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
398 * be used to free the additional reference created by this macro.
400 * \return A new reference to the object located or NULL if nothing is found.
402 #define ASTOBJ_CONTAINER_FIND(container,namestr) \
403 ({ \
404 typeof((container)->head) found = NULL; \
405 ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
406 if (!(strcasecmp(iterator->name, (namestr)))) \
407 found = ASTOBJ_REF(iterator); \
408 } while (0)); \
409 found; \
412 /*! \brief Find an object in a container.
414 * \param container A pointer to the container to search.
415 * \param data The data to search for.
416 * \param field The field/member of the container's objects to search.
417 * \param hashfunc The hash function to use, currently not implemented.
418 * \param hashoffset The hash offset to use, currently not implemented.
419 * \param comparefunc The function used to compare the field and data values.
421 * This macro iterates through a container passing the specified field and data
422 * elements to the specified comparefunc. The function should return 0 when a match is found.
424 * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
425 * be used to free the additional reference created by this macro.
427 * \return A pointer to the object located or NULL if nothing is found.
429 #define ASTOBJ_CONTAINER_FIND_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
430 ({ \
431 typeof((container)->head) found = NULL; \
432 ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
433 ASTOBJ_RDLOCK(iterator); \
434 if (!(comparefunc(iterator->field, (data)))) { \
435 found = ASTOBJ_REF(iterator); \
437 ASTOBJ_UNLOCK(iterator); \
438 } while (0)); \
439 found; \
442 /*! \brief Empty a container.
444 * \param container A pointer to the container to operate on.
445 * \param destructor A destructor function to call on each object.
447 * This macro loops through a container removing all the items from it using
448 * #ASTOBJ_UNREF(). This does not destroy the container itself, use
449 * #ASTOBJ_CONTAINER_DESTROY() for that.
451 * \note If any object in the container is only referenced by the container,
452 * the destructor will be called for that object once it has been removed.
454 #define ASTOBJ_CONTAINER_DESTROYALL(container,destructor) \
455 do { \
456 typeof((container)->head) iterator; \
457 ASTOBJ_CONTAINER_WRLOCK(container); \
458 while((iterator = (container)->head)) { \
459 (container)->head = (iterator)->next[0]; \
460 ASTOBJ_UNREF(iterator,destructor); \
462 ASTOBJ_CONTAINER_UNLOCK(container); \
463 } while(0)
465 /*! \brief Remove an object from a container.
467 * \param container A pointer to the container to operate on.
468 * \param obj A pointer to the object to remove.
470 * This macro iterates through a container and removes the specfied object if
471 * it exists in the container.
473 * \note This macro does not destroy any objects, it simply unlinks
474 * them from the list. No destructors are called.
476 * \return The container's reference to the removed object or NULL if no
477 * matching object was found.
479 #define ASTOBJ_CONTAINER_UNLINK(container,obj) \
480 ({ \
481 typeof((container)->head) found = NULL; \
482 typeof((container)->head) prev = NULL; \
483 ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
484 if (iterator == obj) { \
485 found = iterator; \
486 found->next[0] = NULL; \
487 ASTOBJ_CONTAINER_WRLOCK(container); \
488 if (prev) \
489 prev->next[0] = next; \
490 else \
491 (container)->head = next; \
492 ASTOBJ_CONTAINER_UNLOCK(container); \
494 prev = iterator; \
495 } while (0)); \
496 found; \
499 /*! \brief Find and remove an object from a container.
501 * \param container A pointer to the container to operate on.
502 * \param namestr The name of the object to remove.
504 * This macro iterates through a container and removes the first object with
505 * the specfied name from the container.
507 * \note This macro does not destroy any objects, it simply unlinks
508 * them. No destructors are called.
510 * \return The container's reference to the removed object or NULL if no
511 * matching object was found.
513 #define ASTOBJ_CONTAINER_FIND_UNLINK(container,namestr) \
514 ({ \
515 typeof((container)->head) found = NULL; \
516 typeof((container)->head) prev = NULL; \
517 ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
518 if (!(strcasecmp(iterator->name, (namestr)))) { \
519 found = iterator; \
520 found->next[0] = NULL; \
521 ASTOBJ_CONTAINER_WRLOCK(container); \
522 if (prev) \
523 prev->next[0] = next; \
524 else \
525 (container)->head = next; \
526 ASTOBJ_CONTAINER_UNLOCK(container); \
528 prev = iterator; \
529 } while (0)); \
530 found; \
533 /*! \brief Find and remove an object in a container.
535 * \param container A pointer to the container to search.
536 * \param data The data to search for.
537 * \param field The field/member of the container's objects to search.
538 * \param hashfunc The hash function to use, currently not implemented.
539 * \param hashoffset The hash offset to use, currently not implemented.
540 * \param comparefunc The function used to compare the field and data values.
542 * This macro iterates through a container passing the specified field and data
543 * elements to the specified comparefunc. The function should return 0 when a match is found.
544 * If a match is found it is removed from the list.
546 * \note This macro does not destroy any objects, it simply unlinks
547 * them. No destructors are called.
549 * \return The container's reference to the removed object or NULL if no match
550 * was found.
552 #define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
553 ({ \
554 typeof((container)->head) found = NULL; \
555 typeof((container)->head) prev = NULL; \
556 ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
557 ASTOBJ_RDLOCK(iterator); \
558 if (!(comparefunc(iterator->field, (data)))) { \
559 found = iterator; \
560 found->next[0] = NULL; \
561 ASTOBJ_CONTAINER_WRLOCK(container); \
562 if (prev) \
563 prev->next[0] = next; \
564 else \
565 (container)->head = next; \
566 ASTOBJ_CONTAINER_UNLOCK(container); \
568 ASTOBJ_UNLOCK(iterator); \
569 prev = iterator; \
570 } while (0)); \
571 found; \
574 /*! \brief Add an object to the end of a container.
576 * \param container A pointer to the container to operate on.
577 * \param newobj A pointer to the object to be added.
579 * This macro adds an object to the end of a container.
581 #define ASTOBJ_CONTAINER_LINK_END(container,newobj) \
582 do { \
583 typeof((container)->head) iterator; \
584 typeof((container)->head) next; \
585 typeof((container)->head) prev; \
586 ASTOBJ_CONTAINER_RDLOCK(container); \
587 prev = NULL; \
588 next = (container)->head; \
589 while((iterator = next)) { \
590 next = iterator->next[0]; \
591 prev = iterator; \
593 if(prev) { \
594 ASTOBJ_CONTAINER_WRLOCK((container)); \
595 prev->next[0] = ASTOBJ_REF(newobj); \
596 (newobj)->next[0] = NULL; \
597 ASTOBJ_CONTAINER_UNLOCK((container)); \
598 } else { \
599 ASTOBJ_CONTAINER_LINK_START((container),(newobj)); \
601 ASTOBJ_CONTAINER_UNLOCK((container)); \
602 } while(0)
604 /*! \brief Add an object to the front of a container.
606 * \param container A pointer to the container to operate on.
607 * \param newobj A pointer to the object to be added.
609 * This macro adds an object to the start of a container.
611 #define ASTOBJ_CONTAINER_LINK_START(container,newobj) \
612 do { \
613 ASTOBJ_CONTAINER_WRLOCK(container); \
614 (newobj)->next[0] = (container)->head; \
615 (container)->head = ASTOBJ_REF(newobj); \
616 ASTOBJ_CONTAINER_UNLOCK(container); \
617 } while(0)
619 /*! \brief Remove an object from the front of a container.
621 * \param container A pointer to the container to operate on.
623 * This macro removes the first object in a container.
625 * \note This macro does not destroy any objects, it simply unlinks
626 * them from the list. No destructors are called.
628 * \return The container's reference to the removed object or NULL if no
629 * matching object was found.
631 #define ASTOBJ_CONTAINER_UNLINK_START(container) \
632 ({ \
633 typeof((container)->head) found = NULL; \
634 ASTOBJ_CONTAINER_WRLOCK(container); \
635 if((container)->head) { \
636 found = (container)->head; \
637 (container)->head = (container)->head->next[0]; \
638 found->next[0] = NULL; \
640 ASTOBJ_CONTAINER_UNLOCK(container); \
641 found; \
644 /*! \brief Prune marked objects from a container.
646 * \param container A pointer to the container to prune.
647 * \param destructor A destructor function to call on each marked object.
649 * This macro iterates through the specfied container and prunes any marked
650 * objects executing the specfied destructor if necessary.
652 #define ASTOBJ_CONTAINER_PRUNE_MARKED(container,destructor) \
653 do { \
654 typeof((container)->head) prev = NULL; \
655 ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { \
656 ASTOBJ_RDLOCK(iterator); \
657 if (iterator->objflags & ASTOBJ_FLAG_MARKED) { \
658 ASTOBJ_CONTAINER_WRLOCK(container); \
659 if (prev) \
660 prev->next[0] = next; \
661 else \
662 (container)->head = next; \
663 ASTOBJ_CONTAINER_UNLOCK(container); \
664 ASTOBJ_UNLOCK(iterator); \
665 ASTOBJ_UNREF(iterator,destructor); \
666 continue; \
668 ASTOBJ_UNLOCK(iterator); \
669 prev = iterator; \
670 } while (0)); \
671 } while(0)
673 /*! \brief Add an object to a container.
675 * \param container A pointer to the container to operate on.
676 * \param newobj A pointer to the object to be added.
677 * \param data Currently unused.
678 * \param field Currently unused.
679 * \param hashfunc Currently unused.
680 * \param hashoffset Currently unused.
681 * \param comparefunc Currently unused.
683 * Currently this function adds an object to the head of the list. One day it
684 * will support adding objects atthe position specified using the various
685 * options this macro offers.
687 #define ASTOBJ_CONTAINER_LINK_FULL(container,newobj,data,field,hashfunc,hashoffset,comparefunc) \
688 do { \
689 ASTOBJ_CONTAINER_WRLOCK(container); \
690 (newobj)->next[0] = (container)->head; \
691 (container)->head = ASTOBJ_REF(newobj); \
692 ASTOBJ_CONTAINER_UNLOCK(container); \
693 } while(0)
695 #endif /* List model */
697 /* Common to hash and linked list models */
699 /*! \brief Create a container for ASTOBJs (without locking support).
701 * \param type The type of objects the container will hold.
703 * This macro is used to create a container for ASTOBJs without locking
704 * support.
706 * <b>Sample Usage:</b>
707 * \code
708 * struct sample_struct_nolock_container {
709 * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(struct sample_struct);
710 * };
711 * \endcode
713 #define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type) \
714 ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,1,ASTOBJ_DEFAULT_BUCKETS)
717 /*! \brief Create a container for ASTOBJs (with locking support).
719 * \param type The type of objects the container will hold.
721 * This macro is used to create a container for ASTOBJs with locking support.
723 * <b>Sample Usage:</b>
724 * \code
725 * struct sample_struct_container {
726 * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
727 * };
728 * \endcode
730 #define ASTOBJ_CONTAINER_COMPONENTS(type) \
731 ast_mutex_t _lock; \
732 ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type)
734 /*! \brief Initialize a container.
736 * \param container A pointer to the container to initialize.
738 * This macro initializes a container. It should only be used on containers
739 * that support locking.
741 * <b>Sample Usage:</b>
742 * \code
743 * struct sample_struct_container {
744 * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
745 * } container;
747 * int func()
749 * ASTOBJ_CONTAINER_INIT(&container);
751 * \endcode
753 #define ASTOBJ_CONTAINER_INIT(container) \
754 ASTOBJ_CONTAINER_INIT_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
756 /*! \brief Destroy a container.
758 * \param container A pointer to the container to destory.
760 * This macro frees up resources used by a container. It does not operate on
761 * the objects in the container. To unlink the objects from the container use
762 * #ASTOBJ_CONTAINER_DESTROYALL().
764 * \note This macro should only be used on containers with locking support.
766 #define ASTOBJ_CONTAINER_DESTROY(container) \
767 ASTOBJ_CONTAINER_DESTROY_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
769 /*! \brief Add an object to a container.
771 * \param container A pointer to the container to operate on.
772 * \param newobj A pointer to the object to be added.
774 * Currently this macro adds an object to the head of a container. One day it
775 * should add an object in alphabetical order.
777 #define ASTOBJ_CONTAINER_LINK(container,newobj) \
778 ASTOBJ_CONTAINER_LINK_FULL(container,newobj,(newobj)->name,name,ASTOBJ_DEFAULT_HASH,0,strcasecmp)
780 /*! \brief Mark all the objects in a container.
781 * \param container A pointer to the container to operate on.
783 #define ASTOBJ_CONTAINER_MARKALL(container) \
784 ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_MARK(iterator))
786 /*! \brief Unmark all the objects in a container.
787 * \param container A pointer to the container to operate on.
789 #define ASTOBJ_CONTAINER_UNMARKALL(container) \
790 ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_UNMARK(iterator))
792 /*! \brief Dump information about an object into a string.
794 * \param s A pointer to the string buffer to use.
795 * \param slen The length of s.
796 * \param obj A pointer to the object to dump.
798 * This macro dumps a text representation of the name, objectflags, and
799 * refcount fields of an object to the specfied string buffer.
801 #define ASTOBJ_DUMP(s,slen,obj) \
802 snprintf((s),(slen),"name: %s\nobjflags: %d\nrefcount: %d\n\n", (obj)->name, (obj)->objflags, (obj)->refcount);
804 /*! \brief Dump information about all the objects in a container to a file descriptor.
806 * \param fd The file descriptor to write to.
807 * \param s A string buffer, same as #ASTOBJ_DUMP().
808 * \param slen The length of s, same as #ASTOBJ_DUMP().
809 * \param container A pointer to the container to dump.
811 * This macro dumps a text representation of the name, objectflags, and
812 * refcount fields of all the objects in a container to the specified file
813 * descriptor.
815 #define ASTOBJ_CONTAINER_DUMP(fd,s,slen,container) \
816 ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { ASTOBJ_DUMP(s,slen,iterator); ast_cli(fd, "%s", s); } while(0))
818 #if defined(__cplusplus) || defined(c_plusplus)
820 #endif
822 #endif /* _ASTERISK_ASTOBJ_H */