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