9f5e05d4312013e424d751acd190842c5c5e8ce4
[asterisk/asterisk.git] / main / astobj2.c
1 /*
2  * astobj2 - replacement containers for asterisk data structures.
3  *
4  * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Functions implementing astobj2 objects.
20  *
21  * \author Richard Mudgett <rmudgett@digium.com>
22  */
23
24 /*** MODULEINFO
25         <support_level>core</support_level>
26  ***/
27
28 #include "asterisk.h"
29
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
31
32 #include "asterisk/_private.h"
33 #include "asterisk/astobj2.h"
34 #include "asterisk/dlinkedlists.h"
35 #include "asterisk/utils.h"
36 #include "asterisk/cli.h"
37 #define REF_FILE "/tmp/refs"
38
39 #if defined(TEST_FRAMEWORK)
40 /* We are building with the test framework enabled so enable AO2 debug tests as well. */
41 #define AO2_DEBUG 1
42 #endif  /* defined(TEST_FRAMEWORK) */
43
44 /*!
45  * astobj2 objects are always preceded by this data structure,
46  * which contains a reference counter,
47  * option flags and a pointer to a destructor.
48  * The refcount is used to decide when it is time to
49  * invoke the destructor.
50  * The magic number is used for consistency check.
51  */
52 struct __priv_data {
53         int ref_counter;
54         ao2_destructor_fn destructor_fn;
55         /*! User data size for stats */
56         size_t data_size;
57         /*! The ao2 object option flags */
58         uint32_t options;
59         /*! magic number.  This is used to verify that a pointer passed in is a
60          *  valid astobj2 */
61         uint32_t magic;
62 };
63
64 #define AO2_MAGIC       0xa570b123
65
66 /*!
67  * What an astobj2 object looks like: fixed-size private data
68  * followed by variable-size user data.
69  */
70 struct astobj2 {
71         struct __priv_data priv_data;
72         void *user_data[0];
73 };
74
75 struct ao2_lock_priv {
76         ast_mutex_t lock;
77 };
78
79 /* AstObj2 with recursive lock. */
80 struct astobj2_lock {
81         struct ao2_lock_priv mutex;
82         struct __priv_data priv_data;
83         void *user_data[0];
84 };
85
86 struct ao2_rwlock_priv {
87         ast_rwlock_t lock;
88         /*! Count of the number of threads holding a lock on this object. -1 if it is the write lock. */
89         int num_lockers;
90 };
91
92 /* AstObj2 with RW lock. */
93 struct astobj2_rwlock {
94         struct ao2_rwlock_priv rwlock;
95         struct __priv_data priv_data;
96         void *user_data[0];
97 };
98
99 #if defined(AST_DEVMODE)
100 #define AO2_DEVMODE_STAT(stat)  stat
101 #else
102 #define AO2_DEVMODE_STAT(stat)
103 #endif  /* defined(AST_DEVMODE) */
104
105 #ifdef AO2_DEBUG
106 struct ao2_stats {
107         volatile int total_objects;
108         volatile int total_mem;
109         volatile int total_containers;
110         volatile int total_refs;
111         volatile int total_locked;
112 };
113
114 static struct ao2_stats ao2;
115 #endif
116
117 #ifndef HAVE_BKTR       /* backtrace support */
118 void ao2_bt(void) {}
119 #else
120 #include <execinfo.h>    /* for backtrace */
121
122 void ao2_bt(void)
123 {
124         int c, i;
125 #define N1      20
126         void *addresses[N1];
127         char **strings;
128
129         c = backtrace(addresses, N1);
130         strings = ast_bt_get_symbols(addresses,c);
131         ast_verbose("backtrace returned: %d\n", c);
132         for(i = 0; i < c; i++) {
133                 ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]);
134         }
135         free(strings);
136 }
137 #endif
138
139 #define INTERNAL_OBJ_MUTEX(user_data) \
140         ((struct astobj2_lock *) (((char *) (user_data)) - sizeof(struct astobj2_lock)))
141
142 #define INTERNAL_OBJ_RWLOCK(user_data) \
143         ((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock)))
144
145 /*!
146  * \brief convert from a pointer _p to a user-defined object
147  *
148  * \return the pointer to the astobj2 structure
149  */
150 static inline struct astobj2 *INTERNAL_OBJ(void *user_data)
151 {
152         struct astobj2 *p;
153
154         if (!user_data) {
155                 ast_log(LOG_ERROR, "user_data is NULL\n");
156                 return NULL;
157         }
158
159         p = (struct astobj2 *) ((char *) user_data - sizeof(*p));
160         if (AO2_MAGIC != p->priv_data.magic) {
161                 if (p->priv_data.magic) {
162                         ast_log(LOG_ERROR, "bad magic number 0x%x for object %p\n",
163                                 p->priv_data.magic, user_data);
164                 } else {
165                         ast_log(LOG_ERROR,
166                                 "bad magic number for object %p. Object is likely destroyed.\n",
167                                 user_data);
168                 }
169                 return NULL;
170         }
171
172         return p;
173 }
174
175 /*!
176  * \brief convert from a pointer _p to an astobj2 object
177  *
178  * \return the pointer to the user-defined portion.
179  */
180 #define EXTERNAL_OBJ(_p)        ((_p) == NULL ? NULL : (_p)->user_data)
181
182 int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
183 {
184         struct astobj2 *obj = INTERNAL_OBJ(user_data);
185         struct astobj2_lock *obj_mutex;
186         struct astobj2_rwlock *obj_rwlock;
187         int res = 0;
188
189         if (obj == NULL) {
190                 ast_assert(0);
191                 return -1;
192         }
193
194         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
195         case AO2_ALLOC_OPT_LOCK_MUTEX:
196                 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
197                 res = __ast_pthread_mutex_lock(file, line, func, var, &obj_mutex->mutex.lock);
198 #ifdef AO2_DEBUG
199                 if (!res) {
200                         ast_atomic_fetchadd_int(&ao2.total_locked, 1);
201                 }
202 #endif
203                 break;
204         case AO2_ALLOC_OPT_LOCK_RWLOCK:
205                 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
206                 switch (lock_how) {
207                 case AO2_LOCK_REQ_MUTEX:
208                 case AO2_LOCK_REQ_WRLOCK:
209                         res = __ast_rwlock_wrlock(file, line, func, &obj_rwlock->rwlock.lock, var);
210                         if (!res) {
211                                 ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1);
212 #ifdef AO2_DEBUG
213                                 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
214 #endif
215                         }
216                         break;
217                 case AO2_LOCK_REQ_RDLOCK:
218                         res = __ast_rwlock_rdlock(file, line, func, &obj_rwlock->rwlock.lock, var);
219                         if (!res) {
220                                 ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, +1);
221 #ifdef AO2_DEBUG
222                                 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
223 #endif
224                         }
225                         break;
226                 }
227                 break;
228         case AO2_ALLOC_OPT_LOCK_NOLOCK:
229                 /* The ao2 object has no lock. */
230                 break;
231         default:
232                 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
233                         user_data);
234                 return -1;
235         }
236
237         return res;
238 }
239
240 int __ao2_unlock(void *user_data, const char *file, const char *func, int line, const char *var)
241 {
242         struct astobj2 *obj = INTERNAL_OBJ(user_data);
243         struct astobj2_lock *obj_mutex;
244         struct astobj2_rwlock *obj_rwlock;
245         int res = 0;
246         int current_value;
247
248         if (obj == NULL) {
249                 ast_assert(0);
250                 return -1;
251         }
252
253         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
254         case AO2_ALLOC_OPT_LOCK_MUTEX:
255                 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
256                 res = __ast_pthread_mutex_unlock(file, line, func, var, &obj_mutex->mutex.lock);
257 #ifdef AO2_DEBUG
258                 if (!res) {
259                         ast_atomic_fetchadd_int(&ao2.total_locked, -1);
260                 }
261 #endif
262                 break;
263         case AO2_ALLOC_OPT_LOCK_RWLOCK:
264                 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
265
266                 current_value = ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1) - 1;
267                 if (current_value < 0) {
268                         /* It was a WRLOCK that we are unlocking.  Fix the count. */
269                         ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -current_value);
270                 }
271                 res = __ast_rwlock_unlock(file, line, func, &obj_rwlock->rwlock.lock, var);
272 #ifdef AO2_DEBUG
273                 if (!res) {
274                         ast_atomic_fetchadd_int(&ao2.total_locked, -1);
275                 }
276 #endif
277                 break;
278         case AO2_ALLOC_OPT_LOCK_NOLOCK:
279                 /* The ao2 object has no lock. */
280                 break;
281         default:
282                 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
283                         user_data);
284                 res = -1;
285                 break;
286         }
287         return res;
288 }
289
290 int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
291 {
292         struct astobj2 *obj = INTERNAL_OBJ(user_data);
293         struct astobj2_lock *obj_mutex;
294         struct astobj2_rwlock *obj_rwlock;
295         int res = 0;
296
297         if (obj == NULL) {
298                 ast_assert(0);
299                 return -1;
300         }
301
302         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
303         case AO2_ALLOC_OPT_LOCK_MUTEX:
304                 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
305                 res = __ast_pthread_mutex_trylock(file, line, func, var, &obj_mutex->mutex.lock);
306 #ifdef AO2_DEBUG
307                 if (!res) {
308                         ast_atomic_fetchadd_int(&ao2.total_locked, 1);
309                 }
310 #endif
311                 break;
312         case AO2_ALLOC_OPT_LOCK_RWLOCK:
313                 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
314                 switch (lock_how) {
315                 case AO2_LOCK_REQ_MUTEX:
316                 case AO2_LOCK_REQ_WRLOCK:
317                         res = __ast_rwlock_trywrlock(file, line, func, &obj_rwlock->rwlock.lock, var);
318                         if (!res) {
319                                 ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1);
320 #ifdef AO2_DEBUG
321                                 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
322 #endif
323                         }
324                         break;
325                 case AO2_LOCK_REQ_RDLOCK:
326                         res = __ast_rwlock_tryrdlock(file, line, func, &obj_rwlock->rwlock.lock, var);
327                         if (!res) {
328                                 ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, +1);
329 #ifdef AO2_DEBUG
330                                 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
331 #endif
332                         }
333                         break;
334                 }
335                 break;
336         case AO2_ALLOC_OPT_LOCK_NOLOCK:
337                 /* The ao2 object has no lock. */
338                 return 0;
339         default:
340                 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
341                         user_data);
342                 return -1;
343         }
344
345
346         return res;
347 }
348
349 /*!
350  * \internal
351  * \brief Adjust an object's lock to the requested level.
352  *
353  * \param user_data An ao2 object to adjust lock level.
354  * \param lock_how What level to adjust lock.
355  * \param keep_stronger TRUE if keep original lock level if it is stronger.
356  *
357  * \pre The ao2 object is already locked.
358  *
359  * \details
360  * An ao2 object with a RWLOCK will have its lock level adjusted
361  * to the specified level if it is not already there.  An ao2
362  * object with a different type of lock is not affected.
363  *
364  * \return Original lock level.
365  */
366 static enum ao2_lock_req adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger)
367 {
368         struct astobj2 *obj = INTERNAL_OBJ(user_data);
369         struct astobj2_rwlock *obj_rwlock;
370         enum ao2_lock_req orig_lock;
371
372         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
373         case AO2_ALLOC_OPT_LOCK_RWLOCK:
374                 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
375                 if (obj_rwlock->rwlock.num_lockers < 0) {
376                         orig_lock = AO2_LOCK_REQ_WRLOCK;
377                 } else {
378                         orig_lock = AO2_LOCK_REQ_RDLOCK;
379                 }
380                 switch (lock_how) {
381                 case AO2_LOCK_REQ_MUTEX:
382                         lock_how = AO2_LOCK_REQ_WRLOCK;
383                         /* Fall through */
384                 case AO2_LOCK_REQ_WRLOCK:
385                         if (lock_how != orig_lock) {
386                                 /* Switch from read lock to write lock. */
387                                 ao2_unlock(user_data);
388                                 ao2_wrlock(user_data);
389                         }
390                         break;
391                 case AO2_LOCK_REQ_RDLOCK:
392                         if (!keep_stronger && lock_how != orig_lock) {
393                                 /* Switch from write lock to read lock. */
394                                 ao2_unlock(user_data);
395                                 ao2_rdlock(user_data);
396                         }
397                         break;
398                 }
399                 break;
400         default:
401                 ast_log(LOG_ERROR, "Invalid lock option on ao2 object %p\n", user_data);
402                 /* Fall through */
403         case AO2_ALLOC_OPT_LOCK_NOLOCK:
404         case AO2_ALLOC_OPT_LOCK_MUTEX:
405                 orig_lock = AO2_LOCK_REQ_MUTEX;
406                 break;
407         }
408
409         return orig_lock;
410 }
411
412 void *ao2_object_get_lockaddr(void *user_data)
413 {
414         struct astobj2 *obj = INTERNAL_OBJ(user_data);
415         struct astobj2_lock *obj_mutex;
416
417         if (obj == NULL) {
418                 ast_assert(0);
419                 return NULL;
420         }
421
422         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
423         case AO2_ALLOC_OPT_LOCK_MUTEX:
424                 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
425                 return &obj_mutex->mutex.lock;
426         default:
427                 break;
428         }
429
430         return NULL;
431 }
432
433 static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *func)
434 {
435         struct astobj2 *obj = INTERNAL_OBJ(user_data);
436         struct astobj2_lock *obj_mutex;
437         struct astobj2_rwlock *obj_rwlock;
438         int current_value;
439         int ret;
440
441         if (obj == NULL) {
442                 ast_assert(0);
443                 return -1;
444         }
445
446         /* if delta is 0, just return the refcount */
447         if (delta == 0) {
448                 return obj->priv_data.ref_counter;
449         }
450
451         /* we modify with an atomic operation the reference counter */
452         ret = ast_atomic_fetchadd_int(&obj->priv_data.ref_counter, delta);
453         current_value = ret + delta;
454
455 #ifdef AO2_DEBUG
456         ast_atomic_fetchadd_int(&ao2.total_refs, delta);
457 #endif
458
459         if (0 < current_value) {
460                 /* The object still lives. */
461                 return ret;
462         }
463
464         /* this case must never happen */
465         if (current_value < 0) {
466                 ast_log(__LOG_ERROR, file, line, func,
467                         "Invalid refcount %d on ao2 object %p\n", current_value, user_data);
468         }
469
470         /* last reference, destroy the object */
471         if (obj->priv_data.destructor_fn != NULL) {
472                 obj->priv_data.destructor_fn(user_data);
473         }
474
475 #ifdef AO2_DEBUG
476         ast_atomic_fetchadd_int(&ao2.total_mem, - obj->priv_data.data_size);
477         ast_atomic_fetchadd_int(&ao2.total_objects, -1);
478 #endif
479
480         switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
481         case AO2_ALLOC_OPT_LOCK_MUTEX:
482                 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
483                 ast_mutex_destroy(&obj_mutex->mutex.lock);
484
485                 /*
486                  * For safety, zero-out the astobj2_lock header and also the
487                  * first word of the user-data, which we make sure is always
488                  * allocated.
489                  */
490                 memset(obj_mutex, '\0', sizeof(*obj_mutex) + sizeof(void *) );
491                 ast_free(obj_mutex);
492                 break;
493         case AO2_ALLOC_OPT_LOCK_RWLOCK:
494                 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
495                 ast_rwlock_destroy(&obj_rwlock->rwlock.lock);
496
497                 /*
498                  * For safety, zero-out the astobj2_rwlock header and also the
499                  * first word of the user-data, which we make sure is always
500                  * allocated.
501                  */
502                 memset(obj_rwlock, '\0', sizeof(*obj_rwlock) + sizeof(void *) );
503                 ast_free(obj_rwlock);
504                 break;
505         case AO2_ALLOC_OPT_LOCK_NOLOCK:
506                 /*
507                  * For safety, zero-out the astobj2 header and also the first
508                  * word of the user-data, which we make sure is always
509                  * allocated.
510                  */
511                 memset(obj, '\0', sizeof(*obj) + sizeof(void *) );
512                 ast_free(obj);
513                 break;
514         default:
515                 ast_log(__LOG_ERROR, file, line, func,
516                         "Invalid lock option on ao2 object %p\n", user_data);
517                 break;
518         }
519
520         return ret;
521 }
522
523 int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
524 {
525         struct astobj2 *obj = INTERNAL_OBJ(user_data);
526
527         if (obj == NULL) {
528                 ast_backtrace();
529                 ast_assert(0);
530                 return -1;
531         }
532
533         if (delta != 0) {
534                 FILE *refo = fopen(REF_FILE, "a");
535                 if (refo) {
536                         fprintf(refo, "%p %s%d   %s:%d:%s (%s) [@%d]\n", user_data, (delta < 0 ? "" : "+"),
537                                 delta, file, line, func, tag, obj->priv_data.ref_counter);
538                         fclose(refo);
539                 }
540         }
541         if (obj->priv_data.ref_counter + delta == 0 && obj->priv_data.destructor_fn != NULL) { /* this isn't protected with lock; just for o/p */
542                 FILE *refo = fopen(REF_FILE, "a");
543                 if (refo) {
544                         fprintf(refo, "%p **call destructor** %s:%d:%s (%s)\n", user_data, file, line, func, tag);
545                         fclose(refo);
546                 }
547         }
548         return internal_ao2_ref(user_data, delta, file, line, func);
549 }
550
551 int __ao2_ref(void *user_data, int delta)
552 {
553         return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
554 }
555
556 void __ao2_cleanup_debug(void *obj, const char *file, int line, const char *function)
557 {
558         if (obj) {
559                 __ao2_ref_debug(obj, -1, "ao2_cleanup", file, line, function);
560         }
561 }
562
563 void __ao2_cleanup(void *obj)
564 {
565         if (obj) {
566                 ao2_ref(obj, -1);
567         }
568 }
569
570 static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *file, int line, const char *func)
571 {
572         /* allocation */
573         struct astobj2 *obj;
574         struct astobj2_lock *obj_mutex;
575         struct astobj2_rwlock *obj_rwlock;
576
577         if (data_size < sizeof(void *)) {
578                 /*
579                  * We always alloc at least the size of a void *,
580                  * for debugging purposes.
581                  */
582                 data_size = sizeof(void *);
583         }
584
585         switch (options & AO2_ALLOC_OPT_LOCK_MASK) {
586         case AO2_ALLOC_OPT_LOCK_MUTEX:
587 #if defined(__AST_DEBUG_MALLOC)
588                 obj_mutex = __ast_calloc(1, sizeof(*obj_mutex) + data_size, file, line, func);
589 #else
590                 obj_mutex = ast_calloc(1, sizeof(*obj_mutex) + data_size);
591 #endif
592                 if (obj_mutex == NULL) {
593                         return NULL;
594                 }
595
596                 ast_mutex_init(&obj_mutex->mutex.lock);
597                 obj = (struct astobj2 *) &obj_mutex->priv_data;
598                 break;
599         case AO2_ALLOC_OPT_LOCK_RWLOCK:
600 #if defined(__AST_DEBUG_MALLOC)
601                 obj_rwlock = __ast_calloc(1, sizeof(*obj_rwlock) + data_size, file, line, func);
602 #else
603                 obj_rwlock = ast_calloc(1, sizeof(*obj_rwlock) + data_size);
604 #endif
605                 if (obj_rwlock == NULL) {
606                         return NULL;
607                 }
608
609                 ast_rwlock_init(&obj_rwlock->rwlock.lock);
610                 obj = (struct astobj2 *) &obj_rwlock->priv_data;
611                 break;
612         case AO2_ALLOC_OPT_LOCK_NOLOCK:
613 #if defined(__AST_DEBUG_MALLOC)
614                 obj = __ast_calloc(1, sizeof(*obj) + data_size, file, line, func);
615 #else
616                 obj = ast_calloc(1, sizeof(*obj) + data_size);
617 #endif
618                 if (obj == NULL) {
619                         return NULL;
620                 }
621                 break;
622         default:
623                 /* Invalid option value. */
624                 ast_log(__LOG_DEBUG, file, line, func, "Invalid lock option requested\n");
625                 return NULL;
626         }
627
628         /* Initialize common ao2 values. */
629         obj->priv_data.ref_counter = 1;
630         obj->priv_data.destructor_fn = destructor_fn;   /* can be NULL */
631         obj->priv_data.data_size = data_size;
632         obj->priv_data.options = options;
633         obj->priv_data.magic = AO2_MAGIC;
634
635 #ifdef AO2_DEBUG
636         ast_atomic_fetchadd_int(&ao2.total_objects, 1);
637         ast_atomic_fetchadd_int(&ao2.total_mem, data_size);
638         ast_atomic_fetchadd_int(&ao2.total_refs, 1);
639 #endif
640
641         /* return a pointer to the user data */
642         return EXTERNAL_OBJ(obj);
643 }
644
645 void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
646         const char *file, int line, const char *func, int ref_debug)
647 {
648         /* allocation */
649         void *obj;
650         FILE *refo;
651
652         if ((obj = internal_ao2_alloc(data_size, destructor_fn, options, file, line, func)) == NULL) {
653                 return NULL;
654         }
655
656         if (ref_debug && (refo = fopen(REF_FILE, "a"))) {
657                 fprintf(refo, "%p =1   %s:%d:%s (%s)\n", obj, file, line, func, tag);
658                 fclose(refo);
659         }
660
661         /* return a pointer to the user data */
662         return obj;
663 }
664
665 void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options)
666 {
667         return internal_ao2_alloc(data_size, destructor_fn, options, __FILE__, __LINE__, __FUNCTION__);
668 }
669
670
671 void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name)
672 {
673         if (!holder) {
674                 /* For sanity */
675                 ast_log(LOG_ERROR, "Must be called with a global object!\n");
676                 ast_assert(0);
677                 return;
678         }
679         if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) {
680                 /* Could not get the write lock. */
681                 ast_assert(0);
682                 return;
683         }
684
685         /* Release the held ao2 object. */
686         if (holder->obj) {
687                 if (tag) {
688                         __ao2_ref_debug(holder->obj, -1, tag, file, line, func);
689                 } else {
690                         __ao2_ref(holder->obj, -1);
691                 }
692                 holder->obj = NULL;
693         }
694
695         __ast_rwlock_unlock(file, line, func, &holder->lock, name);
696 }
697
698 void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
699 {
700         void *obj_old;
701
702         if (!holder) {
703                 /* For sanity */
704                 ast_log(LOG_ERROR, "Must be called with a global object!\n");
705                 ast_assert(0);
706                 return NULL;
707         }
708         if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) {
709                 /* Could not get the write lock. */
710                 ast_assert(0);
711                 return NULL;
712         }
713
714         if (obj) {
715                 if (tag) {
716                         __ao2_ref_debug(obj, +1, tag, file, line, func);
717                 } else {
718                         __ao2_ref(obj, +1);
719                 }
720         }
721         obj_old = holder->obj;
722         holder->obj = obj;
723
724         __ast_rwlock_unlock(file, line, func, &holder->lock, name);
725
726         return obj_old;
727 }
728
729 int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
730 {
731         void *obj_old;
732
733         obj_old = __ao2_global_obj_replace(holder, obj, tag, file, line, func, name);
734         if (obj_old) {
735                 if (tag) {
736                         __ao2_ref_debug(obj_old, -1, tag, file, line, func);
737                 } else {
738                         __ao2_ref(obj_old, -1);
739                 }
740                 return 1;
741         }
742         return 0;
743 }
744
745 void *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name)
746 {
747         void *obj;
748
749         if (!holder) {
750                 /* For sanity */
751                 ast_log(LOG_ERROR, "Must be called with a global object!\n");
752                 ast_assert(0);
753                 return NULL;
754         }
755
756         if (__ast_rwlock_rdlock(file, line, func, &holder->lock, name)) {
757                 /* Could not get the read lock. */
758                 ast_assert(0);
759                 return NULL;
760         }
761
762         obj = holder->obj;
763         if (obj) {
764                 if (tag) {
765                         __ao2_ref_debug(obj, +1, tag, file, line, func);
766                 } else {
767                         __ao2_ref(obj, +1);
768                 }
769         }
770
771         __ast_rwlock_unlock(file, line, func, &holder->lock, name);
772
773         return obj;
774 }
775
776 enum ao2_callback_type {
777         AO2_CALLBACK_DEFAULT,
778         AO2_CALLBACK_WITH_DATA,
779 };
780
781 enum ao2_container_insert {
782         /*! The node was inserted into the container. */
783         AO2_CONTAINER_INSERT_NODE_INSERTED,
784         /*! The node object replaced an existing node object. */
785         AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED,
786         /*! The node was rejected (duplicate). */
787         AO2_CONTAINER_INSERT_NODE_REJECTED,
788 };
789
790 enum ao2_container_rtti {
791         /*! This is a hash container */
792         AO2_CONTAINER_RTTI_HASH,
793         /*! This is a red-black tree container */
794         AO2_CONTAINER_RTTI_RBTREE,
795 };
796
797 /*!
798  * \brief Generic container node.
799  *
800  * \details This is the base container node type that contains
801  * values common to all container nodes.
802  */
803 struct ao2_container_node {
804         /*! Stored object in node. */
805         void *obj;
806         /*! Container holding the node.  (Does not hold a reference.) */
807         struct ao2_container *my_container;
808         /*! TRUE if the node is linked into the container. */
809         unsigned int is_linked:1;
810 };
811
812 /*!
813  * \brief Destroy this container.
814  *
815  * \param self Container to operate upon.
816  *
817  * \return Nothing
818  */
819 typedef void (*ao2_container_destroy_fn)(struct ao2_container *self);
820
821 /*!
822  * \brief Create an empty copy of this container.
823  *
824  * \param self Container to operate upon.
825  *
826  * \retval empty-container on success.
827  * \retval NULL on error.
828  */
829 typedef struct ao2_container *(*ao2_container_alloc_empty_clone_fn)(struct ao2_container *self);
830
831 /*!
832  * \brief Create an empty copy of this container. (Debug version)
833  *
834  * \param self Container to operate upon.
835  * \param tag used for debugging.
836  * \param file Debug file name invoked from
837  * \param line Debug line invoked from
838  * \param func Debug function name invoked from
839  * \param ref_debug TRUE if to output a debug reference message.
840  *
841  * \retval empty-container on success.
842  * \retval NULL on error.
843  */
844 typedef struct ao2_container *(*ao2_container_alloc_empty_clone_debug_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func, int ref_debug);
845
846 /*!
847  * \brief Create a new container node.
848  *
849  * \param self Container to operate upon.
850  * \param obj_new Object to put into the node.
851  * \param tag used for debugging.
852  * \param file Debug file name invoked from
853  * \param line Debug line invoked from
854  * \param func Debug function name invoked from
855  *
856  * \retval initialized-node on success.
857  * \retval NULL on error.
858  */
859 typedef struct ao2_container_node *(*ao2_container_new_node_fn)(struct ao2_container *self, void *obj_new, const char *tag, const char *file, int line, const char *func);
860
861 /*!
862  * \brief Insert a node into this container.
863  *
864  * \param self Container to operate upon.
865  * \param node Container node to insert into the container.
866  *
867  * \return enum ao2_container_insert value.
868  */
869 typedef enum ao2_container_insert (*ao2_container_insert_fn)(struct ao2_container *self, struct ao2_container_node *node);
870
871 /*!
872  * \brief Find the first container node in a traversal.
873  *
874  * \param self Container to operate upon.
875  * \param flags search_flags to control traversing the container
876  * \param arg Comparison callback arg parameter.
877  * \param v_state Traversal state to restart container traversal.
878  *
879  * \retval node-ptr of found node (Reffed).
880  * \retval NULL when no node found.
881  */
882 typedef struct ao2_container_node *(*ao2_container_find_first_fn)(struct ao2_container *self, enum search_flags flags, void *arg, void *v_state);
883
884 /*!
885  * \brief Find the next container node in a traversal.
886  *
887  * \param self Container to operate upon.
888  * \param v_state Traversal state to restart container traversal.
889  * \param prev Previous node returned by the traversal search functions.
890  *    The ref ownership is passed back to this function.
891  *
892  * \retval node-ptr of found node (Reffed).
893  * \retval NULL when no node found.
894  */
895 typedef struct ao2_container_node *(*ao2_container_find_next_fn)(struct ao2_container *self, void *v_state, struct ao2_container_node *prev);
896
897 /*!
898  * \brief Cleanup the container traversal state.
899  *
900  * \param v_state Traversal state to cleanup.
901  *
902  * \return Nothing
903  */
904 typedef void (*ao2_container_find_cleanup_fn)(void *v_state);
905
906 /*!
907  * \brief Find the next non-empty iteration node in the container.
908  *
909  * \param self Container to operate upon.
910  * \param prev Previous node returned by the iterator.
911  * \param flags search_flags to control iterating the container.
912  *   Only AO2_ITERATOR_DESCENDING is useful by the method.
913  *
914  * \note The container is already locked.
915  *
916  * \retval node on success.
917  * \retval NULL on error or no more nodes in the container.
918  */
919 typedef struct ao2_container_node *(*ao2_iterator_next_fn)(struct ao2_container *self, struct ao2_container_node *prev, enum ao2_iterator_flags flags);
920
921 /*!
922  * \brief Display contents of the specified container.
923  *
924  * \param self Container to dump.
925  * \param where User data needed by prnt to determine where to put output.
926  * \param prnt Print output callback function to use.
927  * \param prnt_obj Callback function to print the given object's key. (NULL if not available)
928  *
929  * \return Nothing
930  */
931 typedef void (*ao2_container_display)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj);
932
933 /*!
934  * \brief Display statistics of the specified container.
935  *
936  * \param self Container to display statistics.
937  * \param where User data needed by prnt to determine where to put output.
938  * \param prnt Print output callback function to use.
939  *
940  * \note The container is already locked for reading.
941  *
942  * \return Nothing
943  */
944 typedef void (*ao2_container_statistics)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt);
945
946 /*!
947  * \brief Perform an integrity check on the specified container.
948  *
949  * \param self Container to check integrity.
950  *
951  * \note The container is already locked for reading.
952  *
953  * \retval 0 on success.
954  * \retval -1 on error.
955  */
956 typedef int (*ao2_container_integrity)(struct ao2_container *self);
957
958 /*! Container virtual methods template. */
959 struct ao2_container_methods {
960         /*! Run Time Type Identification */
961         enum ao2_container_rtti type;
962         /*! Destroy this container. */
963         ao2_container_destroy_fn destroy;
964         /*! \brief Create an empty copy of this container. */
965         ao2_container_alloc_empty_clone_fn alloc_empty_clone;
966         /*! \brief Create an empty copy of this container. (Debug version) */
967         ao2_container_alloc_empty_clone_debug_fn alloc_empty_clone_debug;
968         /*! Create a new container node. */
969         ao2_container_new_node_fn new_node;
970         /*! Insert a node into this container. */
971         ao2_container_insert_fn insert;
972         /*! Traverse the container, find the first node. */
973         ao2_container_find_first_fn traverse_first;
974         /*! Traverse the container, find the next node. */
975         ao2_container_find_next_fn traverse_next;
976         /*! Traverse the container, cleanup state. */
977         ao2_container_find_cleanup_fn traverse_cleanup;
978         /*! Find the next iteration element in the container. */
979         ao2_iterator_next_fn iterator_next;
980 #if defined(AST_DEVMODE)
981         /*! Display container contents. (Method for debug purposes) */
982         ao2_container_display dump;
983         /*! Display container debug statistics. (Method for debug purposes) */
984         ao2_container_statistics stats;
985         /*! Perform an integrity check on the container. (Method for debug purposes) */
986         ao2_container_integrity integrity;
987 #endif  /* defined(AST_DEVMODE) */
988 };
989
990 /*!
991  * \brief Generic container type.
992  *
993  * \details This is the base container type that contains values
994  * common to all container types.
995  *
996  * \todo Linking and unlinking container objects is typically
997  * expensive, as it involves a malloc()/free() of a small object
998  * which is very inefficient.  To optimize this, we can allocate
999  * larger arrays of container nodes when we run out of them, and
1000  * then manage our own freelist.  This will be more efficient as
1001  * we can do the freelist management while we hold the lock
1002  * (that we need anyway).
1003  */
1004 struct ao2_container {
1005         /*! Container virtual method table. */
1006         const struct ao2_container_methods *v_table;
1007         /*! Container sort function if the container is sorted. */
1008         ao2_sort_fn *sort_fn;
1009         /*! Container traversal matching function for ao2_find. */
1010         ao2_callback_fn *cmp_fn;
1011         /*! The container option flags */
1012         uint32_t options;
1013         /*! Number of elements in the container. */
1014         int elements;
1015 #if defined(AST_DEVMODE)
1016         /*! Number of nodes in the container. */
1017         int nodes;
1018         /*! Maximum number of empty nodes in the container. (nodes - elements) */
1019         int max_empty_nodes;
1020 #endif  /* defined(AST_DEVMODE) */
1021         /*!
1022          * \brief TRUE if the container is being destroyed.
1023          *
1024          * \note The destruction traversal should override any requested
1025          * search order to do the most efficient order for destruction.
1026          *
1027          * \note There should not be any empty nodes in the container
1028          * during destruction.  If there are then an error needs to be
1029          * issued about container node reference leaks.
1030          */
1031         unsigned int destroying:1;
1032 };
1033
1034 /*!
1035  * return the number of elements in the container
1036  */
1037 int ao2_container_count(struct ao2_container *c)
1038 {
1039         return ast_atomic_fetchadd_int(&c->elements, 0);
1040 }
1041
1042 #if defined(AST_DEVMODE)
1043 static void hash_ao2_link_node_stat(struct ao2_container *hash, struct ao2_container_node *hash_node);
1044 static void hash_ao2_unlink_node_stat(struct ao2_container *hash, struct ao2_container_node *hash_node);
1045 #endif  /* defined(AST_DEVMODE) */
1046
1047 /*!
1048  * \internal
1049  * \brief Link an object into this container.  (internal)
1050  *
1051  * \param self Container to operate upon.
1052  * \param obj_new Object to insert into the container.
1053  * \param flags search_flags to control linking the object.  (OBJ_NOLOCK)
1054  * \param tag used for debugging.
1055  * \param file Debug file name invoked from
1056  * \param line Debug line invoked from
1057  * \param func Debug function name invoked from
1058  *
1059  * \retval 0 on errors.
1060  * \retval 1 on success.
1061  */
1062 static int internal_ao2_link(struct ao2_container *self, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
1063 {
1064         int res;
1065         enum ao2_lock_req orig_lock;
1066         struct ao2_container_node *node;
1067
1068         if (!INTERNAL_OBJ(obj_new) || !INTERNAL_OBJ(self)
1069                 || !self->v_table || !self->v_table->new_node || !self->v_table->insert) {
1070                 /* Sanity checks. */
1071                 ast_assert(0);
1072                 return 0;
1073         }
1074
1075         if (flags & OBJ_NOLOCK) {
1076                 orig_lock = adjust_lock(self, AO2_LOCK_REQ_WRLOCK, 1);
1077         } else {
1078                 ao2_wrlock(self);
1079                 orig_lock = AO2_LOCK_REQ_MUTEX;
1080         }
1081
1082         res = 0;
1083         node = self->v_table->new_node(self, obj_new, tag, file, line, func);
1084         if (node) {
1085 #if defined(AO2_DEBUG) && defined(AST_DEVMODE)
1086                 switch (self->v_table->type) {
1087                 case AO2_CONTAINER_RTTI_HASH:
1088                         if (!self->sort_fn) {
1089                                 /*
1090                                  * XXX chan_iax2 plays games with the hash function so we cannot
1091                                  * routinely do an integrity check on this type of container.
1092                                  * chan_iax2 should be changed to not abuse the hash function.
1093                                  */
1094                                 break;
1095                         }
1096                         /* Fall through. */
1097                 case AO2_CONTAINER_RTTI_RBTREE:
1098                         if (ao2_container_check(self, OBJ_NOLOCK)) {
1099                                 ast_log(LOG_ERROR, "Container integrity failed before insert.\n");
1100                         }
1101                         break;
1102                 }
1103 #endif  /* defined(AO2_DEBUG) && defined(AST_DEVMODE) */
1104                 /* Insert the new node. */
1105                 switch (self->v_table->insert(self, node)) {
1106                 case AO2_CONTAINER_INSERT_NODE_INSERTED:
1107                         node->is_linked = 1;
1108                         ast_atomic_fetchadd_int(&self->elements, 1);
1109 #if defined(AST_DEVMODE)
1110                         AO2_DEVMODE_STAT(++self->nodes);
1111                         switch (self->v_table->type) {
1112                         case AO2_CONTAINER_RTTI_HASH:
1113                                 hash_ao2_link_node_stat(self, node);
1114                                 break;
1115                         case AO2_CONTAINER_RTTI_RBTREE:
1116                                 break;
1117                         }
1118 #endif  /* defined(AST_DEVMODE) */
1119
1120                         res = 1;
1121                         break;
1122                 case AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED:
1123                         res = 1;
1124                         /* Fall through */
1125                 case AO2_CONTAINER_INSERT_NODE_REJECTED:
1126                         __ao2_ref(node, -1);
1127                         break;
1128                 }
1129 #if defined(AO2_DEBUG) && defined(AST_DEVMODE)
1130                 if (res) {
1131                         switch (self->v_table->type) {
1132                         case AO2_CONTAINER_RTTI_HASH:
1133                                 if (!self->sort_fn) {
1134                                         /*
1135                                          * XXX chan_iax2 plays games with the hash function so we cannot
1136                                          * routinely do an integrity check on this type of container.
1137                                          * chan_iax2 should be changed to not abuse the hash function.
1138                                          */
1139                                         break;
1140                                 }
1141                                 /* Fall through. */
1142                         case AO2_CONTAINER_RTTI_RBTREE:
1143                                 if (ao2_container_check(self, OBJ_NOLOCK)) {
1144                                         ast_log(LOG_ERROR, "Container integrity failed after insert.\n");
1145                                 }
1146                                 break;
1147                         }
1148                 }
1149 #endif  /* defined(AO2_DEBUG) && defined(AST_DEVMODE) */
1150         }
1151
1152         if (flags & OBJ_NOLOCK) {
1153                 adjust_lock(self, orig_lock, 0);
1154         } else {
1155                 ao2_unlock(self);
1156         }
1157
1158         return res;
1159 }
1160
1161 int __ao2_link_debug(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
1162 {
1163         return internal_ao2_link(c, obj_new, flags, tag, file, line, func);
1164 }
1165
1166 int __ao2_link(struct ao2_container *c, void *obj_new, int flags)
1167 {
1168         return internal_ao2_link(c, obj_new, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
1169 }
1170
1171 /*!
1172  * \brief another convenience function is a callback that matches on address
1173  */
1174 int ao2_match_by_addr(void *user_data, void *arg, int flags)
1175 {
1176         return (user_data == arg) ? (CMP_MATCH | CMP_STOP) : 0;
1177 }
1178
1179 /*
1180  * Unlink an object from the container
1181  * and destroy the associated * bucket_entry structure.
1182  */
1183 void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
1184         const char *tag, const char *file, int line, const char *func)
1185 {
1186         if (!INTERNAL_OBJ(user_data)) {
1187                 /* Sanity checks. */
1188                 ast_assert(0);
1189                 return NULL;
1190         }
1191
1192         flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
1193         __ao2_callback_debug(c, flags, ao2_match_by_addr, user_data, tag, file, line, func);
1194
1195         return NULL;
1196 }
1197
1198 void *__ao2_unlink(struct ao2_container *c, void *user_data, int flags)
1199 {
1200         if (!INTERNAL_OBJ(user_data)) {
1201                 /* Sanity checks. */
1202                 ast_assert(0);
1203                 return NULL;
1204         }
1205
1206         flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
1207         __ao2_callback(c, flags, ao2_match_by_addr, user_data);
1208
1209         return NULL;
1210 }
1211
1212 /*!
1213  * \brief special callback that matches all
1214  */
1215 static int cb_true(void *user_data, void *arg, int flags)
1216 {
1217         return CMP_MATCH;
1218 }
1219
1220 /*!
1221  * \brief similar to cb_true, but is an ao2_callback_data_fn instead
1222  */
1223 static int cb_true_data(void *user_data, void *arg, void *data, int flags)
1224 {
1225         return CMP_MATCH;
1226 }
1227
1228 /*! Allow enough room for container specific traversal state structs */
1229 #define AO2_TRAVERSAL_STATE_SIZE        100
1230
1231 /*!
1232  * \internal
1233  * \brief Traverse the container.  (internal)
1234  *
1235  * \param self Container to operate upon.
1236  * \param flags search_flags to control traversing the container
1237  * \param cb_fn Comparison callback function.
1238  * \param arg Comparison callback arg parameter.
1239  * \param data Data comparison callback data parameter.
1240  * \param type Type of comparison callback cb_fn.
1241  * \param tag used for debugging.
1242  * \param file Debug file name invoked from
1243  * \param line Debug line invoked from
1244  * \param func Debug function name invoked from
1245  *
1246  * \retval NULL on failure or no matching object found.
1247  *
1248  * \retval object found if OBJ_MULTIPLE is not set in the flags
1249  * parameter.
1250  *
1251  * \retval ao2_iterator pointer if OBJ_MULTIPLE is set in the
1252  * flags parameter.  The iterator must be destroyed with
1253  * ao2_iterator_destroy() when the caller no longer needs it.
1254  */
1255 static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags flags,
1256         void *cb_fn, void *arg, void *data, enum ao2_callback_type type,
1257         const char *tag, const char *file, int line, const char *func)
1258 {
1259         void *ret;
1260         ao2_callback_fn *cb_default = NULL;
1261         ao2_callback_data_fn *cb_withdata = NULL;
1262         struct ao2_container_node *node;
1263         void *traversal_state;
1264
1265         enum ao2_lock_req orig_lock;
1266         struct ao2_container *multi_container = NULL;
1267         struct ao2_iterator *multi_iterator = NULL;
1268
1269         if (!INTERNAL_OBJ(self) || !self->v_table || !self->v_table->traverse_first
1270                 || !self->v_table->traverse_next) {
1271                 /* Sanity checks. */
1272                 ast_assert(0);
1273                 return NULL;
1274         }
1275
1276         /*
1277          * This logic is used so we can support OBJ_MULTIPLE with OBJ_NODATA
1278          * turned off.  This if statement checks for the special condition
1279          * where multiple items may need to be returned.
1280          */
1281         if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) {
1282                 /* we need to return an ao2_iterator with the results,
1283                  * as there could be more than one. the iterator will
1284                  * hold the only reference to a container that has all the
1285                  * matching objects linked into it, so when the iterator
1286                  * is destroyed, the container will be automatically
1287                  * destroyed as well.
1288                  */
1289                 multi_container = ao2_t_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL,
1290                         NULL, "OBJ_MULTIPLE return container creation");
1291                 if (!multi_container) {
1292                         return NULL;
1293                 }
1294                 if (!(multi_iterator = ast_calloc(1, sizeof(*multi_iterator)))) {
1295                         ao2_t_ref(multi_container, -1, "OBJ_MULTIPLE interator creation failed.");
1296                         return NULL;
1297                 }
1298         }
1299
1300         if (!cb_fn) {
1301                 /* Match everything if no callback match function provided. */
1302                 if (type == AO2_CALLBACK_WITH_DATA) {
1303                         cb_withdata = cb_true_data;
1304                 } else {
1305                         cb_default = cb_true;
1306                 }
1307         } else {
1308                 /*
1309                  * We do this here to avoid the per object casting penalty (even
1310                  * though that is probably optimized away anyway).
1311                  */
1312                 if (type == AO2_CALLBACK_WITH_DATA) {
1313                         cb_withdata = cb_fn;
1314                 } else {
1315                         cb_default = cb_fn;
1316                 }
1317         }
1318
1319         /* avoid modifications to the content */
1320         if (flags & OBJ_NOLOCK) {
1321                 if (flags & OBJ_UNLINK) {
1322                         orig_lock = adjust_lock(self, AO2_LOCK_REQ_WRLOCK, 1);
1323                 } else {
1324                         orig_lock = adjust_lock(self, AO2_LOCK_REQ_RDLOCK, 1);
1325                 }
1326         } else {
1327                 orig_lock = AO2_LOCK_REQ_MUTEX;
1328                 if (flags & OBJ_UNLINK) {
1329                         ao2_wrlock(self);
1330                 } else {
1331                         ao2_rdlock(self);
1332                 }
1333         }
1334
1335         /* Create a buffer for the traversal state. */
1336         traversal_state = alloca(AO2_TRAVERSAL_STATE_SIZE);
1337
1338         ret = NULL;
1339         for (node = self->v_table->traverse_first(self, flags, arg, traversal_state);
1340                 node;
1341                 node = self->v_table->traverse_next(self, traversal_state, node)) {
1342                 int match;
1343
1344                 /* Visit the current node. */
1345                 match = (CMP_MATCH | CMP_STOP);
1346                 if (type == AO2_CALLBACK_WITH_DATA) {
1347                         match &= cb_withdata(node->obj, arg, data, flags);
1348                 } else {
1349                         match &= cb_default(node->obj, arg, flags);
1350                 }
1351                 if (match == 0) {
1352                         /* no match, no stop, continue */
1353                         continue;
1354                 }
1355                 if (match == CMP_STOP) {
1356                         /* no match but stop, we are done */
1357                         break;
1358                 }
1359
1360                 /*
1361                  * CMP_MATCH is set here
1362                  *
1363                  * we found the object, performing operations according to flags
1364                  */
1365                 if (node->obj) {
1366                         /* The object is still in the container. */
1367                         if (!(flags & OBJ_NODATA)) {
1368                                 /*
1369                                  * We are returning the object, record the value.  It is
1370                                  * important to handle this case before the unlink.
1371                                  */
1372                                 if (multi_container) {
1373                                         /*
1374                                          * Link the object into the container that will hold the
1375                                          * results.
1376                                          */
1377                                         if (tag) {
1378                                                 __ao2_link_debug(multi_container, node->obj, flags,
1379                                                         tag, file, line, func);
1380                                         } else {
1381                                                 __ao2_link(multi_container, node->obj, flags);
1382                                         }
1383                                 } else {
1384                                         ret = node->obj;
1385                                         /* Returning a single object. */
1386                                         if (!(flags & OBJ_UNLINK)) {
1387                                                 /*
1388                                                  * Bump the ref count since we are not going to unlink and
1389                                                  * transfer the container's object ref to the returned object.
1390                                                  */
1391                                                 if (tag) {
1392                                                         __ao2_ref_debug(ret, 1, tag, file, line, func);
1393                                                 } else {
1394                                                         ao2_t_ref(ret, 1, "Traversal found object");
1395                                                 }
1396                                         }
1397                                 }
1398                         }
1399
1400                         if (flags & OBJ_UNLINK) {
1401                                 /* update number of elements */
1402                                 ast_atomic_fetchadd_int(&self->elements, -1);
1403 #if defined(AST_DEVMODE)
1404                                 {
1405                                         int empty = self->nodes - self->elements;
1406
1407                                         if (self->max_empty_nodes < empty) {
1408                                                 self->max_empty_nodes = empty;
1409                                         }
1410                                 }
1411                                 switch (self->v_table->type) {
1412                                 case AO2_CONTAINER_RTTI_HASH:
1413                                         hash_ao2_unlink_node_stat(self, node);
1414                                         break;
1415                                 case AO2_CONTAINER_RTTI_RBTREE:
1416                                         break;
1417                                 }
1418 #endif  /* defined(AST_DEVMODE) */
1419
1420                                 /*
1421                                  * - When unlinking and not returning the result, OBJ_NODATA is
1422                                  * set, the ref from the container must be decremented.
1423                                  *
1424                                  * - When unlinking with a multi_container the ref from the
1425                                  * original container must be decremented.  This is because the
1426                                  * result is returned in a new container that already holds its
1427                                  * own ref for the object.
1428                                  *
1429                                  * If the ref from the original container is not accounted for
1430                                  * here a memory leak occurs.
1431                                  */
1432                                 if (multi_container || (flags & OBJ_NODATA)) {
1433                                         if (tag) {
1434                                                 __ao2_ref_debug(node->obj, -1, tag, file, line, func);
1435                                         } else {
1436                                                 ao2_t_ref(node->obj, -1, "Unlink container obj reference.");
1437                                         }
1438                                 }
1439                                 node->obj = NULL;
1440
1441                                 /* Unref the node from the container. */
1442                                 __ao2_ref(node, -1);
1443                         }
1444                 }
1445
1446                 if ((match & CMP_STOP) || !(flags & OBJ_MULTIPLE)) {
1447                         /* We found our only (or last) match, so we are done */
1448                         break;
1449                 }
1450         }
1451         if (self->v_table->traverse_cleanup) {
1452                 self->v_table->traverse_cleanup(traversal_state);
1453         }
1454         if (node) {
1455                 /* Unref the node from self->v_table->traverse_first/traverse_next() */
1456                 __ao2_ref(node, -1);
1457         }
1458
1459         if (flags & OBJ_NOLOCK) {
1460                 adjust_lock(self, orig_lock, 0);
1461         } else {
1462                 ao2_unlock(self);
1463         }
1464
1465         /* if multi_container was created, we are returning multiple objects */
1466         if (multi_container) {
1467                 *multi_iterator = ao2_iterator_init(multi_container,
1468                         AO2_ITERATOR_UNLINK | AO2_ITERATOR_MALLOCD);
1469                 ao2_t_ref(multi_container, -1,
1470                         "OBJ_MULTIPLE for multiple objects traversal complete.");
1471                 return multi_iterator;
1472         } else {
1473                 return ret;
1474         }
1475 }
1476
1477 void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
1478         ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
1479         const char *func)
1480 {
1481         return internal_ao2_traverse(c, flags, cb_fn, arg, NULL, AO2_CALLBACK_DEFAULT, tag, file, line, func);
1482 }
1483
1484 void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
1485         ao2_callback_fn *cb_fn, void *arg)
1486 {
1487         return internal_ao2_traverse(c, flags, cb_fn, arg, NULL, AO2_CALLBACK_DEFAULT, NULL, NULL, 0, NULL);
1488 }
1489
1490 void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
1491         ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
1492         int line, const char *func)
1493 {
1494         return internal_ao2_traverse(c, flags, cb_fn, arg, data, AO2_CALLBACK_WITH_DATA, tag, file, line, func);
1495 }
1496
1497 void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
1498         ao2_callback_data_fn *cb_fn, void *arg, void *data)
1499 {
1500         return internal_ao2_traverse(c, flags, cb_fn, arg, data, AO2_CALLBACK_WITH_DATA, NULL, NULL, 0, NULL);
1501 }
1502
1503 /*!
1504  * the find function just invokes the default callback with some reasonable flags.
1505  */
1506 void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
1507         const char *tag, const char *file, int line, const char *func)
1508 {
1509         void *arged = (void *) arg;/* Done to avoid compiler const warning */
1510
1511         if (!c) {
1512                 /* Sanity checks. */
1513                 ast_assert(0);
1514                 return NULL;
1515         }
1516         return __ao2_callback_debug(c, flags, c->cmp_fn, arged, tag, file, line, func);
1517 }
1518
1519 void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags)
1520 {
1521         void *arged = (void *) arg;/* Done to avoid compiler const warning */
1522
1523         if (!c) {
1524                 /* Sanity checks. */
1525                 ast_assert(0);
1526                 return NULL;
1527         }
1528         return __ao2_callback(c, flags, c->cmp_fn, arged);
1529 }
1530
1531 /*!
1532  * initialize an iterator so we start from the first object
1533  */
1534 struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
1535 {
1536         struct ao2_iterator a = {
1537                 .c = c,
1538                 .flags = flags
1539         };
1540
1541         ao2_t_ref(c, +1, "Init iterator with container.");
1542
1543         return a;
1544 }
1545
1546 void ao2_iterator_restart(struct ao2_iterator *iter)
1547 {
1548         /* Release the last container node reference if we have one. */
1549         if (iter->last_node) {
1550                 enum ao2_lock_req orig_lock;
1551
1552                 /*
1553                  * Do a read lock in case the container node unref does not
1554                  * destroy the node.  If the container node is destroyed then
1555                  * the lock will be upgraded to a write lock.
1556                  */
1557                 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
1558                         orig_lock = adjust_lock(iter->c, AO2_LOCK_REQ_RDLOCK, 1);
1559                 } else {
1560                         orig_lock = AO2_LOCK_REQ_MUTEX;
1561                         ao2_rdlock(iter->c);
1562                 }
1563
1564                 __ao2_ref(iter->last_node, -1);
1565                 iter->last_node = NULL;
1566
1567                 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
1568                         adjust_lock(iter->c, orig_lock, 0);
1569                 } else {
1570                         ao2_unlock(iter->c);
1571                 }
1572         }
1573
1574         /* The iteration is no longer complete. */
1575         iter->complete = 0;
1576 }
1577
1578 void ao2_iterator_destroy(struct ao2_iterator *iter)
1579 {
1580         /* Release any last container node reference. */
1581         ao2_iterator_restart(iter);
1582
1583         /* Release the iterated container reference. */
1584         ao2_t_ref(iter->c, -1, "Unref iterator in ao2_iterator_destroy");
1585         iter->c = NULL;
1586
1587         /* Free the malloced iterator. */
1588         if (iter->flags & AO2_ITERATOR_MALLOCD) {
1589                 ast_free(iter);
1590         }
1591 }
1592
1593 void ao2_iterator_cleanup(struct ao2_iterator *iter)
1594 {
1595         if (iter) {
1596                 ao2_iterator_destroy(iter);
1597         }
1598 }
1599
1600 /*
1601  * move to the next element in the container.
1602  */
1603 static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
1604 {
1605         enum ao2_lock_req orig_lock;
1606         struct ao2_container_node *node;
1607         void *ret;
1608
1609         if (!INTERNAL_OBJ(iter->c) || !iter->c->v_table || !iter->c->v_table->iterator_next) {
1610                 /* Sanity checks. */
1611                 ast_assert(0);
1612                 return NULL;
1613         }
1614
1615         if (iter->complete) {
1616                 /* Don't return any more objects. */
1617                 return NULL;
1618         }
1619
1620         if (iter->flags & AO2_ITERATOR_DONTLOCK) {
1621                 if (iter->flags & AO2_ITERATOR_UNLINK) {
1622                         orig_lock = adjust_lock(iter->c, AO2_LOCK_REQ_WRLOCK, 1);
1623                 } else {
1624                         orig_lock = adjust_lock(iter->c, AO2_LOCK_REQ_RDLOCK, 1);
1625                 }
1626         } else {
1627                 orig_lock = AO2_LOCK_REQ_MUTEX;
1628                 if (iter->flags & AO2_ITERATOR_UNLINK) {
1629                         ao2_wrlock(iter->c);
1630                 } else {
1631                         ao2_rdlock(iter->c);
1632                 }
1633         }
1634
1635         node = iter->c->v_table->iterator_next(iter->c, iter->last_node, iter->flags);
1636         if (node) {
1637                 ret = node->obj;
1638
1639                 if (iter->flags & AO2_ITERATOR_UNLINK) {
1640                         /* update number of elements */
1641                         ast_atomic_fetchadd_int(&iter->c->elements, -1);
1642 #if defined(AST_DEVMODE)
1643                         {
1644                                 int empty = iter->c->nodes - iter->c->elements;
1645
1646                                 if (iter->c->max_empty_nodes < empty) {
1647                                         iter->c->max_empty_nodes = empty;
1648                                 }
1649                         }
1650                         switch (iter->c->v_table->type) {
1651                         case AO2_CONTAINER_RTTI_HASH:
1652                                 hash_ao2_unlink_node_stat(iter->c, node);
1653                                 break;
1654                         case AO2_CONTAINER_RTTI_RBTREE:
1655                                 break;
1656                         }
1657 #endif  /* defined(AST_DEVMODE) */
1658
1659                         /* Transfer the object ref from the container to the returned object. */
1660                         node->obj = NULL;
1661
1662                         /* Transfer the container's node ref to the iterator. */
1663                 } else {
1664                         /* Bump ref of returned object */
1665                         if (tag) {
1666                                 __ao2_ref_debug(ret, +1, tag, file, line, func);
1667                         } else {
1668                                 ao2_t_ref(ret, +1, "Next iterator object.");
1669                         }
1670
1671                         /* Bump the container's node ref for the iterator. */
1672                         __ao2_ref(node, +1);
1673                 }
1674         } else {
1675                 /* The iteration has completed. */
1676                 iter->complete = 1;
1677                 ret = NULL;
1678         }
1679
1680         /* Replace the iterator's node */
1681         if (iter->last_node) {
1682                 __ao2_ref(iter->last_node, -1);
1683         }
1684         iter->last_node = node;
1685
1686         if (iter->flags & AO2_ITERATOR_DONTLOCK) {
1687                 adjust_lock(iter->c, orig_lock, 0);
1688         } else {
1689                 ao2_unlock(iter->c);
1690         }
1691
1692         return ret;
1693 }
1694
1695 void *__ao2_iterator_next_debug(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
1696 {
1697         return internal_ao2_iterator_next(iter, tag, file, line, func);
1698 }
1699
1700 void *__ao2_iterator_next(struct ao2_iterator *iter)
1701 {
1702         return internal_ao2_iterator_next(iter, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
1703 }
1704
1705 static void container_destruct(void *_c)
1706 {
1707         struct ao2_container *c = _c;
1708
1709         /* Unlink any stored objects in the container. */
1710         c->destroying = 1;
1711         __ao2_callback(c, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
1712
1713         /* Perform any extra container cleanup. */
1714         if (c->v_table && c->v_table->destroy) {
1715                 c->v_table->destroy(c);
1716         }
1717
1718 #ifdef AO2_DEBUG
1719         ast_atomic_fetchadd_int(&ao2.total_containers, -1);
1720 #endif
1721 }
1722
1723 static void container_destruct_debug(void *_c)
1724 {
1725         struct ao2_container *c = _c;
1726
1727         /* Unlink any stored objects in the container. */
1728         c->destroying = 1;
1729         __ao2_callback_debug(c, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL,
1730                 "container_destruct_debug called", __FILE__, __LINE__, __PRETTY_FUNCTION__);
1731
1732         /* Perform any extra container cleanup. */
1733         if (c->v_table && c->v_table->destroy) {
1734                 c->v_table->destroy(c);
1735         }
1736
1737 #ifdef AO2_DEBUG
1738         ast_atomic_fetchadd_int(&ao2.total_containers, -1);
1739 #endif
1740 }
1741
1742 /*!
1743  * \internal
1744  * \brief Put obj into the arg container.
1745  * \since 11.0
1746  *
1747  * \param obj  pointer to the (user-defined part) of an object.
1748  * \param arg callback argument from ao2_callback()
1749  * \param flags flags from ao2_callback()
1750  *
1751  * \retval 0 on success.
1752  * \retval CMP_STOP|CMP_MATCH on error.
1753  */
1754 static int dup_obj_cb(void *obj, void *arg, int flags)
1755 {
1756         struct ao2_container *dest = arg;
1757
1758         return __ao2_link(dest, obj, OBJ_NOLOCK) ? 0 : (CMP_MATCH | CMP_STOP);
1759 }
1760
1761 int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
1762 {
1763         void *obj;
1764         int res = 0;
1765
1766         if (!(flags & OBJ_NOLOCK)) {
1767                 ao2_rdlock(src);
1768                 ao2_wrlock(dest);
1769         }
1770         obj = __ao2_callback(src, OBJ_NOLOCK, dup_obj_cb, dest);
1771         if (obj) {
1772                 /* Failed to put this obj into the dest container. */
1773                 ao2_t_ref(obj, -1, "Failed to put this object into the dest container.");
1774
1775                 /* Remove all items from the dest container. */
1776                 __ao2_callback(dest, OBJ_NOLOCK | OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL,
1777                         NULL);
1778                 res = -1;
1779         }
1780         if (!(flags & OBJ_NOLOCK)) {
1781                 ao2_unlock(dest);
1782                 ao2_unlock(src);
1783         }
1784
1785         return res;
1786 }
1787
1788 struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags)
1789 {
1790         struct ao2_container *clone;
1791         int failed;
1792
1793         /* Create the clone container with the same properties as the original. */
1794         if (!INTERNAL_OBJ(orig) || !orig->v_table || !orig->v_table->alloc_empty_clone) {
1795                 /* Sanity checks. */
1796                 ast_assert(0);
1797                 return NULL;
1798         }
1799         clone = orig->v_table->alloc_empty_clone(orig);
1800         if (!clone) {
1801                 return NULL;
1802         }
1803
1804         if (flags & OBJ_NOLOCK) {
1805                 ao2_wrlock(clone);
1806         }
1807         failed = ao2_container_dup(clone, orig, flags);
1808         if (flags & OBJ_NOLOCK) {
1809                 ao2_unlock(clone);
1810         }
1811         if (failed) {
1812                 /* Object copy into the clone container failed. */
1813                 ao2_t_ref(clone, -1, "Clone creation failed.");
1814                 clone = NULL;
1815         }
1816         return clone;
1817 }
1818
1819 struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func, int ref_debug)
1820 {
1821         struct ao2_container *clone;
1822         int failed;
1823
1824         /* Create the clone container with the same properties as the original. */
1825         if (!INTERNAL_OBJ(orig) || !orig->v_table || !orig->v_table->alloc_empty_clone_debug) {
1826                 /* Sanity checks. */
1827                 ast_assert(0);
1828                 return NULL;
1829         }
1830         clone = orig->v_table->alloc_empty_clone_debug(orig, tag, file, line, func, ref_debug);
1831         if (!clone) {
1832                 return NULL;
1833         }
1834
1835         if (flags & OBJ_NOLOCK) {
1836                 ao2_wrlock(clone);
1837         }
1838         failed = ao2_container_dup(clone, orig, flags);
1839         if (flags & OBJ_NOLOCK) {
1840                 ao2_unlock(clone);
1841         }
1842         if (failed) {
1843                 /* Object copy into the clone container failed. */
1844                 if (ref_debug) {
1845                         __ao2_ref_debug(clone, -1, tag, file, line, func);
1846                 } else {
1847                         ao2_t_ref(clone, -1, "Clone creation failed.");
1848                 }
1849                 clone = NULL;
1850         }
1851         return clone;
1852 }
1853
1854 void ao2_container_dump(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
1855 {
1856         if (!INTERNAL_OBJ(self) || !self->v_table) {
1857                 prnt(where, "Invalid container\n");
1858                 ast_assert(0);
1859                 return;
1860         }
1861
1862         if (!(flags & OBJ_NOLOCK)) {
1863                 ao2_rdlock(self);
1864         }
1865         if (name) {
1866                 prnt(where, "Container name: %s\n", name);
1867         }
1868 #if defined(AST_DEVMODE)
1869         if (self->v_table->dump) {
1870                 self->v_table->dump(self, where, prnt, prnt_obj);
1871         } else
1872 #endif  /* defined(AST_DEVMODE) */
1873         {
1874                 prnt(where, "Container dump not available.\n");
1875         }
1876         if (!(flags & OBJ_NOLOCK)) {
1877                 ao2_unlock(self);
1878         }
1879 }
1880
1881 void ao2_container_stats(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt)
1882 {
1883         if (!INTERNAL_OBJ(self) || !self->v_table) {
1884                 prnt(where, "Invalid container\n");
1885                 ast_assert(0);
1886                 return;
1887         }
1888
1889         if (!(flags & OBJ_NOLOCK)) {
1890                 ao2_rdlock(self);
1891         }
1892         if (name) {
1893                 prnt(where, "Container name: %s\n", name);
1894         }
1895         prnt(where, "Number of objects: %d\n", self->elements);
1896 #if defined(AST_DEVMODE)
1897         prnt(where, "Number of nodes: %d\n", self->nodes);
1898         prnt(where, "Number of empty nodes: %d\n", self->nodes - self->elements);
1899         /*
1900          * XXX
1901          * If the max_empty_nodes count gets out of single digits you
1902          * likely have a code path where ao2_iterator_destroy() is not
1903          * called.
1904          *
1905          * Empty nodes do not harm the container but they do make
1906          * container operations less efficient.
1907          */
1908         prnt(where, "Maximum empty nodes: %d\n", self->max_empty_nodes);
1909         if (self->v_table->stats) {
1910                 self->v_table->stats(self, where, prnt);
1911         }
1912 #endif  /* defined(AST_DEVMODE) */
1913         if (!(flags & OBJ_NOLOCK)) {
1914                 ao2_unlock(self);
1915         }
1916 }
1917
1918 int ao2_container_check(struct ao2_container *self, enum search_flags flags)
1919 {
1920         int res = 0;
1921
1922         if (!INTERNAL_OBJ(self) || !self->v_table) {
1923                 /* Sanity checks. */
1924                 ast_assert(0);
1925                 return -1;
1926         }
1927 #if defined(AST_DEVMODE)
1928         if (!self->v_table->integrity) {
1929                 /* No ingetrigy check available.  Assume container is ok. */
1930                 return 0;
1931         }
1932
1933         if (!(flags & OBJ_NOLOCK)) {
1934                 ao2_rdlock(self);
1935         }
1936         res = self->v_table->integrity(self);
1937         if (!(flags & OBJ_NOLOCK)) {
1938                 ao2_unlock(self);
1939         }
1940 #endif  /* defined(AST_DEVMODE) */
1941         return res;
1942 }
1943
1944 /*!
1945  * A structure to create a linked list of entries,
1946  * used within a bucket.
1947  */
1948 struct hash_bucket_node {
1949         /*!
1950          * \brief Items common to all container nodes.
1951          * \note Must be first in the specific node struct.
1952          */
1953         struct ao2_container_node common;
1954         /*! Next node links in the list. */
1955         AST_DLLIST_ENTRY(hash_bucket_node) links;
1956         /*! Hash bucket holding the node. */
1957         int my_bucket;
1958 };
1959
1960 struct hash_bucket {
1961         /*! List of objects held in the bucket. */
1962         AST_DLLIST_HEAD_NOLOCK(, hash_bucket_node) list;
1963 #if defined(AST_DEVMODE)
1964         /*! Number of elements currently in the bucket. */
1965         int elements;
1966         /*! Maximum number of elements in the bucket. */
1967         int max_elements;
1968 #endif  /* defined(AST_DEVMODE) */
1969 };
1970
1971 /*!
1972  * A hash container in addition to values common to all
1973  * container types, stores the hash callback function, the
1974  * number of hash buckets, and the hash bucket heads.
1975  */
1976 struct ao2_container_hash {
1977         /*!
1978          * \brief Items common to all containers.
1979          * \note Must be first in the specific container struct.
1980          */
1981         struct ao2_container common;
1982         ao2_hash_fn *hash_fn;
1983         /*! Number of hash buckets in this container. */
1984         int n_buckets;
1985         /*! Hash bucket array of n_buckets.  Variable size. */
1986         struct hash_bucket buckets[0];
1987 };
1988
1989 /*!
1990  * \internal
1991  * \brief Create an empty copy of this container.
1992  * \since 12.0.0
1993  *
1994  * \param self Container to operate upon.
1995  *
1996  * \retval empty-clone-container on success.
1997  * \retval NULL on error.
1998  */
1999 static struct ao2_container *hash_ao2_alloc_empty_clone(struct ao2_container_hash *self)
2000 {
2001         struct astobj2 *orig_obj;
2002         unsigned int ao2_options;
2003
2004         /* Get container ao2 options. */
2005         orig_obj = INTERNAL_OBJ(self);
2006         if (!orig_obj) {
2007                 return NULL;
2008         }
2009         ao2_options = orig_obj->priv_data.options;
2010
2011         return ao2_t_container_alloc_hash(ao2_options, self->common.options, self->n_buckets,
2012                 self->hash_fn, self->common.sort_fn, self->common.cmp_fn, "Clone hash container");
2013 }
2014
2015 /*!
2016  * \internal
2017  * \brief Create an empty copy of this container. (Debug version)
2018  * \since 12.0.0
2019  *
2020  * \param self Container to operate upon.
2021  * \param tag used for debugging.
2022  * \param file Debug file name invoked from
2023  * \param line Debug line invoked from
2024  * \param func Debug function name invoked from
2025  * \param ref_debug TRUE if to output a debug reference message.
2026  *
2027  * \retval empty-clone-container on success.
2028  * \retval NULL on error.
2029  */
2030 static struct ao2_container *hash_ao2_alloc_empty_clone_debug(struct ao2_container_hash *self, const char *tag, const char *file, int line, const char *func, int ref_debug)
2031 {
2032         struct astobj2 *orig_obj;
2033         unsigned int ao2_options;
2034
2035         /* Get container ao2 options. */
2036         orig_obj = INTERNAL_OBJ(self);
2037         if (!orig_obj) {
2038                 return NULL;
2039         }
2040         ao2_options = orig_obj->priv_data.options;
2041
2042         return __ao2_container_alloc_hash_debug(ao2_options, self->common.options,
2043                 self->n_buckets, self->hash_fn, self->common.sort_fn, self->common.cmp_fn,
2044                 tag, file, line, func, ref_debug);
2045 }
2046
2047 /*!
2048  * \internal
2049  * \brief Destroy a hash container list node.
2050  * \since 12.0.0
2051  *
2052  * \param v_doomed Container node to destroy.
2053  *
2054  * \details
2055  * The container node unlinks itself from the container as part
2056  * of its destruction.  The node must be destroyed while the
2057  * container is already locked.
2058  *
2059  * \note The container must be locked when the node is
2060  * unreferenced.
2061  *
2062  * \return Nothing
2063  */
2064 static void hash_ao2_node_destructor(void *v_doomed)
2065 {
2066         struct hash_bucket_node *doomed = v_doomed;
2067
2068         if (doomed->common.is_linked) {
2069                 struct ao2_container_hash *my_container;
2070                 struct hash_bucket *bucket;
2071
2072                 /*
2073                  * Promote to write lock if not already there.  Since
2074                  * adjust_lock() can potentially release and block waiting for a
2075                  * write lock, care must be taken to ensure that node references
2076                  * are released before releasing the container references.
2077                  *
2078                  * Node references held by an iterator can only be held while
2079                  * the iterator also holds a reference to the container.  These
2080                  * node references must be unreferenced before the container can
2081                  * be unreferenced to ensure that the node will not get a
2082                  * negative reference and the destructor called twice for the
2083                  * same node.
2084                  */
2085                 my_container = (struct ao2_container_hash *) doomed->common.my_container;
2086                 adjust_lock(my_container, AO2_LOCK_REQ_WRLOCK, 1);
2087
2088 #if defined(AO2_DEBUG) && defined(AST_DEVMODE)
2089                 /*
2090                  * XXX chan_iax2 plays games with the hash function so we cannot
2091                  * routinely do an integrity check on this type of container.
2092                  * chan_iax2 should be changed to not abuse the hash function.
2093                  */
2094                 if (!my_container->common.destroying
2095                         && my_container->common.sort_fn
2096                         && ao2_container_check(doomed->common.my_container, OBJ_NOLOCK)) {
2097                         ast_log(LOG_ERROR, "Container integrity failed before node deletion.\n");
2098                 }
2099 #endif  /* defined(AO2_DEBUG) && defined(AST_DEVMODE) */
2100                 bucket = &my_container->buckets[doomed->my_bucket];
2101                 AST_DLLIST_REMOVE(&bucket->list, doomed, links);
2102                 AO2_DEVMODE_STAT(--my_container->common.nodes);
2103         }
2104
2105         /*
2106          * We could have an object in the node if the container is being
2107          * destroyed or the node had not been linked in yet.
2108          */
2109         if (doomed->common.obj) {
2110                 ao2_t_ref(doomed->common.obj, -1, "Container node destruction");
2111                 doomed->common.obj = NULL;
2112         }
2113 }
2114
2115 /*!
2116  * \internal
2117  * \brief Create a new container node.
2118  * \since 12.0.0
2119  *
2120  * \param self Container to operate upon.
2121  * \param obj_new Object to put into the node.
2122  * \param tag used for debugging.
2123  * \param file Debug file name invoked from
2124  * \param line Debug line invoked from
2125  * \param func Debug function name invoked from
2126  *
2127  * \retval initialized-node on success.
2128  * \retval NULL on error.
2129  */
2130 static struct hash_bucket_node *hash_ao2_new_node(struct ao2_container_hash *self, void *obj_new, const char *tag, const char *file, int line, const char *func)
2131 {
2132         struct hash_bucket_node *node;
2133         int i;
2134
2135         node = __ao2_alloc(sizeof(*node), hash_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
2136         if (!node) {
2137                 return NULL;
2138         }
2139
2140         i = abs(self->hash_fn(obj_new, OBJ_POINTER));
2141         i %= self->n_buckets;
2142
2143         if (tag) {
2144                 __ao2_ref_debug(obj_new, +1, tag, file, line, func);
2145         } else {
2146                 ao2_t_ref(obj_new, +1, "Container node creation");
2147         }
2148         node->common.obj = obj_new;
2149         node->common.my_container = (struct ao2_container *) self;
2150         node->my_bucket = i;
2151
2152         return node;
2153 }
2154
2155 /*!
2156  * \internal
2157  * \brief Insert a node into this container.
2158  * \since 12.0.0
2159  *
2160  * \param self Container to operate upon.
2161  * \param node Container node to insert into the container.
2162  *
2163  * \return enum ao2_container_insert value.
2164  */
2165 static enum ao2_container_insert hash_ao2_insert_node(struct ao2_container_hash *self, struct hash_bucket_node *node)
2166 {
2167         int cmp;
2168         struct hash_bucket *bucket;
2169         struct hash_bucket_node *cur;
2170         ao2_sort_fn *sort_fn;
2171         uint32_t options;
2172
2173         bucket = &self->buckets[node->my_bucket];
2174         sort_fn = self->common.sort_fn;
2175         options = self->common.options;
2176
2177         if (options & AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN) {
2178                 if (sort_fn) {
2179                         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&bucket->list, cur, links) {
2180                                 cmp = sort_fn(cur->common.obj, node->common.obj, OBJ_POINTER);
2181                                 if (cmp > 0) {
2182                                         continue;
2183                                 }
2184                                 if (cmp < 0) {
2185                                         AST_DLLIST_INSERT_AFTER_CURRENT(node, links);
2186                                         return AO2_CONTAINER_INSERT_NODE_INSERTED;
2187                                 }
2188                                 switch (options & AO2_CONTAINER_ALLOC_OPT_DUPS_MASK) {
2189                                 default:
2190                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW:
2191                                         break;
2192                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT:
2193                                         /* Reject all objects with the same key. */
2194                                         return AO2_CONTAINER_INSERT_NODE_REJECTED;
2195                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT:
2196                                         if (cur->common.obj == node->common.obj) {
2197                                                 /* Reject inserting the same object */
2198                                                 return AO2_CONTAINER_INSERT_NODE_REJECTED;
2199                                         }
2200                                         break;
2201                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE:
2202                                         SWAP(cur->common.obj, node->common.obj);
2203                                         return AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED;
2204                                 }
2205                         }
2206                         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
2207                 }
2208                 AST_DLLIST_INSERT_HEAD(&bucket->list, node, links);
2209         } else {
2210                 if (sort_fn) {
2211                         AST_DLLIST_TRAVERSE_SAFE_BEGIN(&bucket->list, cur, links) {
2212                                 cmp = sort_fn(cur->common.obj, node->common.obj, OBJ_POINTER);
2213                                 if (cmp < 0) {
2214                                         continue;
2215                                 }
2216                                 if (cmp > 0) {
2217                                         AST_DLLIST_INSERT_BEFORE_CURRENT(node, links);
2218                                         return AO2_CONTAINER_INSERT_NODE_INSERTED;
2219                                 }
2220                                 switch (options & AO2_CONTAINER_ALLOC_OPT_DUPS_MASK) {
2221                                 default:
2222                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW:
2223                                         break;
2224                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT:
2225                                         /* Reject all objects with the same key. */
2226                                         return AO2_CONTAINER_INSERT_NODE_REJECTED;
2227                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT:
2228                                         if (cur->common.obj == node->common.obj) {
2229                                                 /* Reject inserting the same object */
2230                                                 return AO2_CONTAINER_INSERT_NODE_REJECTED;
2231                                         }
2232                                         break;
2233                                 case AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE:
2234                                         SWAP(cur->common.obj, node->common.obj);
2235                                         return AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED;
2236                                 }
2237                         }
2238                         AST_DLLIST_TRAVERSE_SAFE_END;
2239                 }
2240                 AST_DLLIST_INSERT_TAIL(&bucket->list, node, links);
2241         }
2242         return AO2_CONTAINER_INSERT_NODE_INSERTED;
2243 }
2244
2245 /*! Traversal state to restart a hash container traversal. */
2246 struct hash_traversal_state {
2247         /*! Active sort function in the traversal if not NULL. */
2248         ao2_sort_fn *sort_fn;
2249         /*! Node returned in the sorted starting hash bucket if OBJ_CONTINUE flag set. (Reffed) */
2250         struct hash_bucket_node *first_node;
2251         /*! Saved comparison callback arg pointer. */
2252         void *arg;
2253         /*! Starting hash bucket */
2254         int bucket_start;
2255         /*! Stopping hash bucket */
2256         int bucket_last;
2257         /*! Saved search flags to control traversing the container. */
2258         enum search_flags flags;
2259         /*! TRUE if it is a descending search */
2260         unsigned int descending:1;
2261         /*! TRUE if the starting bucket needs to be rechecked because of sorting skips. */
2262         unsigned int recheck_starting_bucket:1;
2263 };
2264
2265 struct hash_traversal_state_check {
2266         /*
2267          * If we have a division by zero compile error here then there
2268          * is not enough room for the state.  Increase AO2_TRAVERSAL_STATE_SIZE.
2269          */
2270         char check[1 / (AO2_TRAVERSAL_STATE_SIZE / sizeof(struct hash_traversal_state))];
2271 };
2272
2273 /*!
2274  * \internal
2275  * \brief Find the first hash container node in a traversal.
2276  * \since 12.0.0
2277  *
2278  * \param self Container to operate upon.
2279  * \param flags search_flags to control traversing the container
2280  * \param arg Comparison callback arg parameter.
2281  * \param state Traversal state to restart hash container traversal.
2282  *
2283  * \retval node-ptr of found node (Reffed).
2284  * \retval NULL when no node found.
2285  */
2286 static struct hash_bucket_node *hash_ao2_find_first(struct ao2_container_hash *self, enum search_flags flags, void *arg, struct hash_traversal_state *state)
2287 {
2288         struct hash_bucket_node *node;
2289         int bucket_cur;
2290         int cmp;
2291
2292         memset(state, 0, sizeof(*state));
2293         state->arg = arg;
2294         state->flags = flags;
2295
2296         /* Determine traversal order. */
2297         switch (flags & OBJ_ORDER_MASK) {
2298         case OBJ_ORDER_POST:
2299         case OBJ_ORDER_DESCENDING:
2300                 state->descending = 1;
2301                 break;
2302         case OBJ_ORDER_PRE:
2303         case OBJ_ORDER_ASCENDING:
2304         default:
2305                 break;
2306         }
2307
2308         /*
2309          * If lookup by pointer or search key, run the hash and optional
2310          * sort functions.  Otherwise, traverse the whole container.
2311          */
2312         if (flags & (OBJ_POINTER | OBJ_KEY)) {
2313                 /* we know hash can handle this case */
2314                 bucket_cur = abs(self->hash_fn(arg, flags & (OBJ_POINTER | OBJ_KEY)));
2315                 bucket_cur %= self->n_buckets;
2316                 state->sort_fn = self->common.sort_fn;
2317         } else {
2318                 /* don't know, let's scan all buckets */
2319                 bucket_cur = -1;
2320                 state->sort_fn = (flags & OBJ_PARTIAL_KEY) ? self->common.sort_fn : NULL;
2321         }
2322
2323         if (state->descending) {
2324                 /*
2325                  * Determine the search boundaries of a descending traversal.
2326                  *
2327                  * bucket_cur downto state->bucket_last
2328                  */
2329                 if (bucket_cur < 0) {
2330                         bucket_cur = self->n_buckets - 1;
2331                         state->bucket_last = 0;
2332                 } else {
2333                         state->bucket_last = bucket_cur;
2334                 }
2335                 if (flags & OBJ_CONTINUE) {
2336                         state->bucket_last = 0;
2337                         if (state->sort_fn) {
2338                                 state->recheck_starting_bucket = 1;
2339                         }
2340                 }
2341                 state->bucket_start = bucket_cur;
2342
2343                 /* For each bucket */
2344                 for (; state->bucket_last <= bucket_cur; --bucket_cur) {
2345                         /* For each node in the bucket. */
2346                         for (node = AST_DLLIST_LAST(&self->buckets[bucket_cur].list);
2347                                 node;
2348                                 node = AST_DLLIST_PREV(node, links)) {
2349                                 if (!node->common.obj) {
2350                                         /* Node is empty */
2351                                         continue;
2352                                 }
2353
2354                                 if (state->sort_fn) {
2355                                         /* Filter node through the sort_fn */
2356                                         cmp = state->sort_fn(node->common.obj, arg,
2357                                                 flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
2358                                         if (cmp > 0) {
2359                                                 continue;
2360                                         }
2361                                         if (flags & OBJ_CONTINUE) {
2362                                                 /* Remember first node when we wrap around. */
2363                                                 __ao2_ref(node, +1);
2364                                                 state->first_node = node;
2365
2366                                                 /* From now on all nodes are matching */
2367                                                 state->sort_fn = NULL;
2368                                         } else if (cmp < 0) {
2369                                                 /* No more nodes in this bucket are possible to match. */
2370                                                 break;
2371                                         }
2372                                 }
2373
2374                                 /* We have the first traversal node */
2375                                 __ao2_ref(node, +1);
2376                                 return node;
2377                         }
2378
2379                         /* Was this the starting bucket? */
2380                         if (bucket_cur == state->bucket_start
2381                                 && (flags & OBJ_CONTINUE)
2382                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2383                                 /* In case the bucket was empty or none of the nodes matched. */
2384                                 state->sort_fn = NULL;
2385                         }
2386
2387                         /* Was this the first container bucket? */
2388                         if (bucket_cur == 0
2389                                 && (flags & OBJ_CONTINUE)
2390                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2391                                 /* Move to the end to ensure we check every bucket */
2392                                 bucket_cur = self->n_buckets;
2393                                 state->bucket_last = state->bucket_start + 1;
2394                                 if (state->recheck_starting_bucket) {
2395                                         /*
2396                                          * We have to recheck the first part of the starting bucket
2397                                          * because of sorting skips.
2398                                          */
2399                                         state->recheck_starting_bucket = 0;
2400                                         --state->bucket_last;
2401                                 }
2402                         }
2403                 }
2404         } else {
2405                 /*
2406                  * Determine the search boundaries of an ascending traversal.
2407                  *
2408                  * bucket_cur to state->bucket_last-1
2409                  */
2410                 if (bucket_cur < 0) {
2411                         bucket_cur = 0;
2412                         state->bucket_last = self->n_buckets;
2413                 } else {
2414                         state->bucket_last = bucket_cur + 1;
2415                 }
2416                 if (flags & OBJ_CONTINUE) {
2417                         state->bucket_last = self->n_buckets;
2418                         if (state->sort_fn) {
2419                                 state->recheck_starting_bucket = 1;
2420                         }
2421                 }
2422                 state->bucket_start = bucket_cur;
2423
2424                 /* For each bucket */
2425                 for (; bucket_cur < state->bucket_last; ++bucket_cur) {
2426                         /* For each node in the bucket. */
2427                         for (node = AST_DLLIST_FIRST(&self->buckets[bucket_cur].list);
2428                                 node;
2429                                 node = AST_DLLIST_NEXT(node, links)) {
2430                                 if (!node->common.obj) {
2431                                         /* Node is empty */
2432                                         continue;
2433                                 }
2434
2435                                 if (state->sort_fn) {
2436                                         /* Filter node through the sort_fn */
2437                                         cmp = state->sort_fn(node->common.obj, arg,
2438                                                 flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
2439                                         if (cmp < 0) {
2440                                                 continue;
2441                                         }
2442                                         if (flags & OBJ_CONTINUE) {
2443                                                 /* Remember first node when we wrap around. */
2444                                                 __ao2_ref(node, +1);
2445                                                 state->first_node = node;
2446
2447                                                 /* From now on all nodes are matching */
2448                                                 state->sort_fn = NULL;
2449                                         } else if (cmp > 0) {
2450                                                 /* No more nodes in this bucket are possible to match. */
2451                                                 break;
2452                                         }
2453                                 }
2454
2455                                 /* We have the first traversal node */
2456                                 __ao2_ref(node, +1);
2457                                 return node;
2458                         }
2459
2460                         /* Was this the starting bucket? */
2461                         if (bucket_cur == state->bucket_start
2462                                 && (flags & OBJ_CONTINUE)
2463                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2464                                 /* In case the bucket was empty or none of the nodes matched. */
2465                                 state->sort_fn = NULL;
2466                         }
2467
2468                         /* Was this the last container bucket? */
2469                         if (bucket_cur == self->n_buckets - 1
2470                                 && (flags & OBJ_CONTINUE)
2471                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2472                                 /* Move to the beginning to ensure we check every bucket */
2473                                 bucket_cur = -1;
2474                                 state->bucket_last = state->bucket_start;
2475                                 if (state->recheck_starting_bucket) {
2476                                         /*
2477                                          * We have to recheck the first part of the starting bucket
2478                                          * because of sorting skips.
2479                                          */
2480                                         state->recheck_starting_bucket = 0;
2481                                         ++state->bucket_last;
2482                                 }
2483                         }
2484                 }
2485         }
2486
2487         return NULL;
2488 }
2489
2490 /*!
2491  * \internal
2492  * \brief Find the next hash container node in a traversal.
2493  * \since 12.0.0
2494  *
2495  * \param self Container to operate upon.
2496  * \param state Traversal state to restart hash container traversal.
2497  * \param prev Previous node returned by the traversal search functions.
2498  *    The ref ownership is passed back to this function.
2499  *
2500  * \retval node-ptr of found node (Reffed).
2501  * \retval NULL when no node found.
2502  */
2503 static struct hash_bucket_node *hash_ao2_find_next(struct ao2_container_hash *self, struct hash_traversal_state *state, struct hash_bucket_node *prev)
2504 {
2505         struct hash_bucket_node *node;
2506         void *arg;
2507         enum search_flags flags;
2508         int bucket_cur;
2509         int cmp;
2510
2511         arg = state->arg;
2512         flags = state->flags;
2513         bucket_cur = prev->my_bucket;
2514         node = prev;
2515
2516         /*
2517          * This function is structured the same as hash_ao2_find_first()
2518          * intentionally.  We are resuming the search loops from
2519          * hash_ao2_find_first() in order to find the next node.  The
2520          * search loops must be resumed where hash_ao2_find_first()
2521          * returned with the first node.
2522          */
2523         if (state->descending) {
2524                 goto hash_descending_resume;
2525
2526                 /* For each bucket */
2527                 for (; state->bucket_last <= bucket_cur; --bucket_cur) {
2528                         /* For each node in the bucket. */
2529                         for (node = AST_DLLIST_LAST(&self->buckets[bucket_cur].list);
2530                                 node;
2531                                 node = AST_DLLIST_PREV(node, links)) {
2532                                 if (node == state->first_node) {
2533                                         /* We have wrapped back to the starting point. */
2534                                         __ao2_ref(prev, -1);
2535                                         return NULL;
2536                                 }
2537                                 if (!node->common.obj) {
2538                                         /* Node is empty */
2539                                         continue;
2540                                 }
2541
2542                                 if (state->sort_fn) {
2543                                         /* Filter node through the sort_fn */
2544                                         cmp = state->sort_fn(node->common.obj, arg,
2545                                                 flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
2546                                         if (cmp > 0) {
2547                                                 continue;
2548                                         }
2549                                         if (cmp < 0) {
2550                                                 /* No more nodes in this bucket are possible to match. */
2551                                                 break;
2552                                         }
2553                                 }
2554
2555                                 /* We have the next traversal node */
2556                                 __ao2_ref(node, +1);
2557
2558                                 /*
2559                                  * Dereferencing the prev node may result in our next node
2560                                  * object being removed by another thread.  This could happen if
2561                                  * the container uses RW locks and the container was read
2562                                  * locked.
2563                                  */
2564                                 __ao2_ref(prev, -1);
2565                                 if (node->common.obj) {
2566                                         return node;
2567                                 }
2568                                 prev = node;
2569
2570 hash_descending_resume:;
2571                         }
2572
2573                         /* Was this the first container bucket? */
2574                         if (bucket_cur == 0
2575                                 && (flags & OBJ_CONTINUE)
2576                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2577                                 /* Move to the end to ensure we check every bucket */
2578                                 bucket_cur = self->n_buckets;
2579                                 state->bucket_last = state->bucket_start + 1;
2580                                 if (state->recheck_starting_bucket) {
2581                                         /*
2582                                          * We have to recheck the first part of the starting bucket
2583                                          * because of sorting skips.
2584                                          */
2585                                         state->recheck_starting_bucket = 0;
2586                                         --state->bucket_last;
2587                                 }
2588                         }
2589                 }
2590         } else {
2591                 goto hash_ascending_resume;
2592
2593                 /* For each bucket */
2594                 for (; bucket_cur < state->bucket_last; ++bucket_cur) {
2595                         /* For each node in the bucket. */
2596                         for (node = AST_DLLIST_FIRST(&self->buckets[bucket_cur].list);
2597                                 node;
2598                                 node = AST_DLLIST_NEXT(node, links)) {
2599                                 if (node == state->first_node) {
2600                                         /* We have wrapped back to the starting point. */
2601                                         __ao2_ref(prev, -1);
2602                                         return NULL;
2603                                 }
2604                                 if (!node->common.obj) {
2605                                         /* Node is empty */
2606                                         continue;
2607                                 }
2608
2609                                 if (state->sort_fn) {
2610                                         /* Filter node through the sort_fn */
2611                                         cmp = state->sort_fn(node->common.obj, arg,
2612                                                 flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
2613                                         if (cmp < 0) {
2614                                                 continue;
2615                                         }
2616                                         if (cmp > 0) {
2617                                                 /* No more nodes in this bucket are possible to match. */
2618                                                 break;
2619                                         }
2620                                 }
2621
2622                                 /* We have the next traversal node */
2623                                 __ao2_ref(node, +1);
2624
2625                                 /*
2626                                  * Dereferencing the prev node may result in our next node
2627                                  * object being removed by another thread.  This could happen if
2628                                  * the container uses RW locks and the container was read
2629                                  * locked.
2630                                  */
2631                                 __ao2_ref(prev, -1);
2632                                 if (node->common.obj) {
2633                                         return node;
2634                                 }
2635                                 prev = node;
2636
2637 hash_ascending_resume:;
2638                         }
2639
2640                         /* Was this the last container bucket? */
2641                         if (bucket_cur == self->n_buckets - 1
2642                                 && (flags & OBJ_CONTINUE)
2643                                 && (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY))) {
2644                                 /* Move to the beginning to ensure we check every bucket */
2645                                 bucket_cur = -1;
2646                                 state->bucket_last = state->bucket_start;
2647                                 if (state->recheck_starting_bucket) {
2648                                         /*
2649                                          * We have to recheck the first part of the starting bucket
2650                                          * because of sorting skips.
2651                                          */
2652                                         state->recheck_starting_bucket = 0;
2653                                         ++state->bucket_last;
2654                                 }
2655                         }
2656                 }
2657         }
2658
2659         /* No more nodes in the container left to traverse. */
2660         __ao2_ref(prev, -1);
2661         return NULL;
2662 }
2663
2664 /*!
2665  * \internal
2666  * \brief Cleanup the hash container traversal state.
2667  * \since 12.0.0
2668  *
2669  * \param state Traversal state to cleanup.
2670  *
2671  * \return Nothing
2672  */
2673 static void hash_ao2_find_cleanup(struct hash_traversal_state *state)
2674 {
2675         if (state->first_node) {
2676                 __ao2_ref(state->first_node, -1);
2677         }
2678 }
2679
2680 /*!
2681  * \internal
2682  * \brief Find the next non-empty iteration node in the container.
2683  * \since 12.0.0
2684  *
2685  * \param self Container to operate upon.
2686  * \param node Previous node returned by the iterator.
2687  * \param flags search_flags to control iterating the container.
2688  *   Only AO2_ITERATOR_DESCENDING is useful by the method.
2689  *
2690  * \note The container is already locked.
2691  *
2692  * \retval node on success.
2693  * \retval NULL on error or no more nodes in the container.
2694  */
2695 static struct hash_bucket_node *hash_ao2_iterator_next(struct ao2_container_hash *self, struct hash_bucket_node *node, enum ao2_iterator_flags flags)
2696 {
2697         int cur_bucket;
2698
2699         if (flags & AO2_ITERATOR_DESCENDING) {
2700                 if (node) {
2701                         cur_bucket = node->my_bucket;
2702
2703                         /* Find next non-empty node. */
2704                         for (;;) {
2705                                 node = AST_DLLIST_PREV(node, links);
2706                                 if (!node) {
2707                                         break;
2708                                 }
2709                                 if (node->common.obj) {
2710                                         /* Found a non-empty node. */
2711                                         return node;
2712                                 }
2713                         }
2714                 } else {
2715                         /* Find first non-empty node. */
2716                         cur_bucket = self->n_buckets;
2717                 }
2718
2719                 /* Find a non-empty node in the remaining buckets */
2720                 while (0 <= --cur_bucket) {
2721                         node = AST_DLLIST_LAST(&self->buckets[cur_bucket].list);
2722                         while (node) {
2723                                 if (node->common.obj) {
2724                                         /* Found a non-empty node. */
2725                                         return node;
2726                                 }
2727                                 node = AST_DLLIST_PREV(node, links);
2728                         }
2729                 }
2730         } else {
2731                 if (node) {
2732                         cur_bucket = node->my_bucket;
2733
2734                         /* Find next non-empty node. */
2735                         for (;;) {
2736                                 node = AST_DLLIST_NEXT(node, links);
2737                                 if (!node) {
2738                                         break;
2739                                 }
2740                                 if (node->common.obj) {
2741                                         /* Found a non-empty node. */
2742                                         return node;
2743                                 }
2744                         }
2745                 } else {
2746                         /* Find first non-empty node. */
2747                         cur_bucket = -1;
2748                 }
2749
2750                 /* Find a non-empty node in the remaining buckets */
2751                 while (++cur_bucket < self->n_buckets) {
2752                         node = AST_DLLIST_FIRST(&self->buckets[cur_bucket].list);
2753                         while (node) {
2754                                 if (node->common.obj) {
2755                                         /* Found a non-empty node. */
2756                                         return node;
2757                                 }
2758                                 node = AST_DLLIST_NEXT(node, links);
2759                         }
2760                 }
2761         }
2762
2763         /* No more nodes to visit in the container. */
2764         return NULL;
2765 }
2766
2767 #if defined(AST_DEVMODE)
2768 /*!
2769  * \internal
2770  * \brief Increment the hash container linked object statistic.
2771  * \since 12.0.0
2772  *
2773  * \param hash Container to operate upon.
2774  * \param hash_node Container node linking object to.
2775  *
2776  * \return Nothing
2777  */
2778 static void hash_ao2_link_node_stat(struct ao2_container *hash, struct ao2_container_node *hash_node)
2779 {
2780         struct ao2_container_hash *self = (struct ao2_container_hash *) hash;
2781         struct hash_bucket_node *node = (struct hash_bucket_node *) hash_node;
2782         int i = node->my_bucket;
2783
2784         ++self->buckets[i].elements;
2785         if (self->buckets[i].max_elements < self->buckets[i].elements) {
2786                 self->buckets[i].max_elements = self->buckets[i].elements;
2787         }
2788 }
2789 #endif  /* defined(AST_DEVMODE) */
2790
2791 #if defined(AST_DEVMODE)
2792 /*!
2793  * \internal
2794  * \brief Decrement the hash container linked object statistic.
2795  * \since 12.0.0
2796  *
2797  * \param hash Container to operate upon.
2798  * \param hash_node Container node unlinking object from.
2799  *
2800  * \return Nothing
2801  */
2802 static void hash_ao2_unlink_node_stat(struct ao2_container *hash, struct ao2_container_node *hash_node)
2803 {
2804         struct ao2_container_hash *self = (struct ao2_container_hash *) hash;
2805         struct hash_bucket_node *node = (struct hash_bucket_node *) hash_node;
2806
2807         --self->buckets[node->my_bucket].elements;
2808 }
2809 #endif  /* defined(AST_DEVMODE) */
2810
2811 /*!
2812  * \internal
2813  *
2814  * \brief Destroy this container.
2815  * \since 12.0.0
2816  *
2817  * \param self Container to operate upon.
2818  *
2819  * \return Nothing
2820  */
2821 static void hash_ao2_destroy(struct ao2_container_hash *self)
2822 {
2823         int idx;
2824
2825         /* Check that the container no longer has any nodes */
2826         for (idx = self->n_buckets; idx--;) {
2827                 if (!AST_DLLIST_EMPTY(&self->buckets[idx].list)) {
2828                         ast_log(LOG_ERROR, "Node ref leak.  Hash container still has nodes!\n");
2829                         ast_assert(0);
2830                         break;
2831                 }
2832         }
2833 }
2834
2835 #if defined(AST_DEVMODE)
2836 /*!
2837  * \internal
2838  * \brief Display contents of the specified container.
2839  * \since 12.0.0
2840  *
2841  * \param self Container to dump.
2842  * \param where User data needed by prnt to determine where to put output.
2843  * \param prnt Print output callback function to use.
2844  * \param prnt_obj Callback function to print the given object's key. (NULL if not available)
2845  *
2846  * \return Nothing
2847  */
2848 static void hash_ao2_dump(struct ao2_container_hash *self, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
2849 {
2850 #define FORMAT  "%6s, %16s, %16s, %16s, %16s, %s\n"
2851 #define FORMAT2 "%6d, %16p, %16p, %16p, %16p, "
2852
2853         int bucket;
2854         int suppressed_buckets = 0;
2855         struct hash_bucket_node *node;
2856
2857         prnt(where, "Number of buckets: %d\n\n", self->n_buckets);
2858
2859         prnt(where, FORMAT, "Bucket", "Node", "Prev", "Next", "Obj", "Key");
2860         for (bucket = 0; bucket < self->n_buckets; ++bucket) {
2861                 node = AST_DLLIST_FIRST(&self->buckets[bucket].list);
2862                 if (node) {
2863                         suppressed_buckets = 0;
2864                         do {
2865                                 prnt(where, FORMAT2,
2866                                         bucket,
2867                                         node,
2868                                         AST_DLLIST_PREV(node, links),
2869                                         AST_DLLIST_NEXT(node, links),
2870                                         node->common.obj);
2871                                 if (node->common.obj && prnt_obj) {
2872                                         prnt_obj(node->common.obj, where, prnt);
2873                                 }
2874                                 prnt(where, "\n");
2875
2876                                 node = AST_DLLIST_NEXT(node, links);
2877                         } while (node);
2878                 } else if (!suppressed_buckets) {
2879                         suppressed_buckets = 1;
2880                         prnt(where, "...\n");
2881                 }
2882         }
2883
2884 #undef FORMAT
2885 #undef FORMAT2
2886 }
2887 #endif  /* defined(AST_DEVMODE) */
2888
2889 #if defined(AST_DEVMODE)
2890 /*!
2891  * \internal
2892  * \brief Display statistics of the specified container.
2893  * \since 12.0.0
2894  *
2895  * \param self Container to display statistics.
2896  * \param where User data needed by prnt to determine where to put output.
2897  * \param prnt Print output callback function to use.
2898  *
2899  * \note The container is already locked for reading.
2900  *
2901  * \return Nothing
2902  */
2903 static void hash_ao2_stats(struct ao2_container_hash *self, void *where, ao2_prnt_fn *prnt)
2904 {
2905 #define FORMAT  "%10.10s %10.10s %10.10s\n"
2906 #define FORMAT2 "%10d %10d %10d\n"
2907
2908         int bucket;
2909         int suppressed_buckets = 0;
2910
2911         prnt(where, "Number of buckets: %d\n\n", self->n_buckets);
2912
2913         prnt(where, FORMAT, "Bucket", "Objects", "Max");
2914         for (bucket = 0; bucket < self->n_buckets; ++bucket) {
2915                 if (self->buckets[bucket].max_elements) {
2916                         suppressed_buckets = 0;
2917                         prnt(where, FORMAT2, bucket, self->buckets[bucket].elements,
2918                                 self->buckets[bucket].max_elements);
2919                 } else if (!suppressed_buckets) {
2920                         suppressed_buckets = 1;
2921                         prnt(where, "...\n");
2922                 }
2923         }
2924
2925 #undef FORMAT
2926 #undef FORMAT2
2927 }
2928 #endif  /* defined(AST_DEVMODE) */
2929
2930 #if defined(AST_DEVMODE)
2931 /*!
2932  * \internal
2933  * \brief Perform an integrity check on the specified container.
2934  * \since 12.0.0
2935  *
2936  * \param self Container to check integrity.
2937  *
2938  * \note The container is already locked for reading.
2939  *
2940  * \retval 0 on success.
2941  * \retval -1 on error.
2942  */
2943 static int hash_ao2_integrity(struct ao2_container_hash *self)
2944 {
2945         int bucket_exp;
2946         int bucket;
2947         int count_obj;
2948         int count_total_obj;
2949         int count_total_node;
2950         void *obj_last;
2951         struct hash_bucket_node *node;
2952         struct hash_bucket_node *prev;
2953         struct hash_bucket_node *next;
2954
2955         count_total_obj = 0;
2956         count_total_node = 0;
2957
2958         /* For each bucket in the container. */
2959         for (bucket = 0; bucket < self->n_buckets; ++bucket) {
2960                 if (!AST_DLLIST_FIRST(&self->buckets[bucket].list)
2961                         && !AST_DLLIST_LAST(&self->buckets[bucket].list)) {
2962                         /* The bucket list is empty. */
2963                         continue;
2964                 }
2965
2966                 count_obj = 0;
2967                 obj_last = NULL;
2968
2969                 /* Check bucket list links and nodes. */
2970                 node = AST_DLLIST_LAST(&self->buckets[bucket].list);
2971                 if (!node) {
2972                         ast_log(LOG_ERROR, "Bucket %d list tail is NULL when it should not be!\n",
2973                                 bucket);
2974                         return -1;
2975                 }
2976                 if (AST_DLLIST_NEXT(node, links)) {
2977                         ast_log(LOG_ERROR, "Bucket %d list tail node is not the last node!\n",
2978                                 bucket);
2979                         return -1;
2980                 }
2981                 node = AST_DLLIST_FIRST(&self->buckets[bucket].list);
2982                 if (!node) {
2983                         ast_log(LOG_ERROR, "Bucket %d list head is NULL when it should not be!\n",
2984                                 bucket);
2985                         return -1;
2986                 }
2987                 if (AST_DLLIST_PREV(node, links)) {
2988                         ast_log(LOG_ERROR, "Bucket %d list head node is not the first node!\n",
2989                                 bucket);
2990                         return -1;
2991                 }
2992                 for (; node; node = next) {
2993                         /* Check backward link. */
2994                         prev = AST_DLLIST_PREV(node, links);
2995                         if (prev) {
2996                                 if (prev == node) {
2997                                         ast_log(LOG_ERROR, "Bucket %d list node's prev pointer points to itself!\n",
2998                                                 bucket);
2999                                         return -1;
3000                                 }
3001                                 if (node != AST_DLLIST_NEXT(prev, links)) {
3002                                         ast_log(LOG_ERROR, "Bucket %d list node's prev node does not link back!\n",
3003                                                 bucket);
3004                                         return -1;
3005                                 }
3006                         } else if (node != AST_DLLIST_FIRST(&self->buckets[bucket].list)) {
3007                                 ast_log(LOG_ERROR, "Bucket %d backward list chain is broken!\n",
3008                                         bucket);
3009                                 return -1;
3010                         }
3011
3012                         /* Check forward link. */
3013                         next = AST_DLLIST_NEXT(node, links);
3014                         if (next) {
3015                                 if (next == node) {
3016                                         ast_log(LOG_ERROR, "Bucket %d list node's next pointer points to itself!\n",
3017                                                 bucket);
3018                                         return -1;
3019                                 }
3020                                 if (node != AST_DLLIST_PREV(next, links)) {
3021                                         ast_log(LOG_ERROR, "Bucket %d list node's next node does not link back!\n",
3022                                                 bucket);
3023                                         return -1;
3024                                 }
3025                         } else if (node != AST_DLLIST_LAST(&self->buckets[bucket].list)) {
3026                                 ast_log(LOG_ERROR, "Bucket %d forward list chain is broken!\n",
3027                                         bucket);
3028                                 return -1;
3029                         }
3030
3031                         if (bucket != node->my_bucket) {
3032                                 ast_log(LOG_ERROR, "Bucket %d node claims to be in bucket %d!\n",
3033                                         bucket, node->my_bucket);
3034                                 return -1;
3035                         }
3036
3037                         ++count_total_node;
3038                         if (!node->common.obj) {
3039                                 /* Node is empty. */
3040                                 continue;
3041                         }
3042                         ++count_obj;
3043
3044                         /* Check container hash key for expected bucket. */
3045                         bucket_exp = abs(self->hash_fn(node->common.obj, OBJ_POINTER));
3046                         bucket_exp %= self->n_buckets;
3047                         if (bucket != bucket_exp) {
3048                                 ast_log(LOG_ERROR, "Bucket %d node hashes to bucket %d!\n",
3049                                         bucket, bucket_exp);
3050                                 return -1;
3051                         }
3052
3053                         /* Check sort if configured. */
3054                         if (self->common.sort_fn) {
3055                                 if (obj_last
3056                                         && self->common.sort_fn(obj_last, node->common.obj, OBJ_POINTER) > 0) {
3057                                         ast_log(LOG_ERROR, "Bucket %d nodes out of sorted order!\n",
3058                                                 bucket);
3059                                         return -1;
3060                                 }
3061                                 obj_last = node->common.obj;
3062                         }
3063                 }
3064
3065                 /* Check bucket obj count statistic. */
3066                 if (count_obj != self->buckets[bucket].elements) {
3067                         ast_log(LOG_ERROR, "Bucket %d object count of %d does not match stat of %d!\n",
3068                                 bucket, count_obj, self->buckets[bucket].elements);
3069                         return -1;
3070                 }
3071
3072                 /* Accumulate found object counts. */
3073                 count_total_obj += count_obj;
3074         }
3075
3076         /* Check total obj count. */
3077         if (count_total_obj != ao2_container_count(&self->common)) {
3078                 ast_log(LOG_ERROR,
3079                         "Total object count of %d does not match ao2_container_count() of %d!\n",
3080                         count_total_obj, ao2_container_count(&self->common));
3081                 return -1;
3082         }
3083
3084         /* Check total node count. */
3085         if (count_total_node != self->common.nodes) {
3086                 ast_log(LOG_ERROR, "Total node count of %d does not match stat of %d!\n",
3087                         count_total_node, self->common.nodes);
3088                 return -1;
3089         }
3090
3091         return 0;
3092 }
3093 #endif  /* defined(AST_DEVMODE) */
3094
3095 /*! Hash container virtual method table. */
3096 static const struct ao2_container_methods v_table_hash = {
3097         .type = AO2_CONTAINER_RTTI_HASH,
3098         .alloc_empty_clone = (ao2_container_alloc_empty_clone_fn) hash_ao2_alloc_empty_clone,
3099         .alloc_empty_clone_debug =
3100                 (ao2_container_alloc_empty_clone_debug_fn) hash_ao2_alloc_empty_clone_debug,
3101         .new_node = (ao2_container_new_node_fn) hash_ao2_new_node,
3102         .insert = (ao2_container_insert_fn) hash_ao2_insert_node,
3103         .traverse_first = (ao2_container_find_first_fn) hash_ao2_find_first,
3104         .traverse_next = (ao2_container_find_next_fn) hash_ao2_find_next,
3105         .traverse_cleanup = (ao2_container_find_cleanup_fn) hash_ao2_find_cleanup,
3106         .iterator_next = (ao2_iterator_next_fn) hash_ao2_iterator_next,
3107         .destroy = (ao2_container_destroy_fn) hash_ao2_destroy,
3108 #if defined(AST_DEVMODE)
3109         .dump = (ao2_container_display) hash_ao2_dump,
3110         .stats = (ao2_container_statistics) hash_ao2_stats,
3111         .integrity = (ao2_container_integrity) hash_ao2_integrity,
3112 #endif  /* defined(AST_DEVMODE) */
3113 };
3114
3115 /*!
3116  * \brief always zero hash function
3117  *
3118  * it is convenient to have a hash function that always returns 0.
3119  * This is basically used when we want to have a container that is
3120  * a simple linked list.
3121  *
3122  * \returns 0
3123  */
3124 static int hash_zero(const void *user_obj, const int flags)
3125 {
3126         return 0;
3127 }
3128
3129 /*!
3130  * \brief Initialize a hash container with the desired number of buckets.
3131  *
3132  * \param self Container to initialize.
3133  * \param options Container behaviour options (See enum ao2_container_opts)
3134  * \param n_buckets Number of buckets for hash
3135  * \param hash_fn Pointer to a function computing a hash value.
3136  * \param sort_fn Pointer to a sort function.
3137  * \param cmp_fn Pointer to a compare function used by ao2_find.
3138  *
3139  * \return A pointer to a struct container.
3140  */
3141 static struct ao2_container *hash_ao2_container_init(
3142         struct ao2_container_hash *self, unsigned int options, unsigned int n_buckets,
3143         ao2_hash_fn *hash_fn, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
3144 {
3145         if (!self) {
3146                 return NULL;
3147         }
3148
3149         self->common.v_table = &v_table_hash;
3150         self->common.sort_fn = sort_fn;
3151         self->common.cmp_fn = cmp_fn;
3152         self->common.options = options;
3153         self->hash_fn = hash_fn ? hash_fn : hash_zero;
3154         self->n_buckets = n_buckets;
3155
3156 #ifdef AO2_DEBUG
3157         ast_atomic_fetchadd_int(&ao2.total_containers, 1);
3158 #endif
3159
3160         return (struct ao2_container *) self;
3161 }
3162
3163 struct ao2_container *__ao2_container_alloc_hash(unsigned int ao2_options,
3164         unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
3165         ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
3166 {
3167         unsigned int num_buckets;
3168         size_t container_size;
3169         struct ao2_container_hash *self;
3170
3171         num_buckets = hash_fn ? n_buckets : 1;
3172         container_size = sizeof(struct ao2_container_hash) + num_buckets * sizeof(struct hash_bucket);
3173
3174         self = ao2_t_alloc_options(container_size, container_destruct, ao2_options,
3175                 "New hash container");
3176         return hash_ao2_container_init(self, container_options, num_buckets,
3177                 hash_fn, sort_fn, cmp_fn);
3178 }
3179
3180 struct ao2_container *__ao2_container_alloc_hash_debug(unsigned int ao2_options,
3181         unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
3182         ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
3183         const char *tag, const char *file, int line, const char *func, int ref_debug)
3184 {
3185         unsigned int num_buckets;
3186         size_t container_size;
3187         struct ao2_container_hash *self;
3188
3189         num_buckets = hash_fn ? n_buckets : 1;
3190         container_size = sizeof(struct ao2_container_hash) + num_buckets * sizeof(struct hash_bucket);
3191
3192         self = __ao2_alloc_debug(container_size, container_destruct_debug, ao2_options,
3193                 tag, file, line, func, ref_debug);
3194         return hash_ao2_container_init(self, container_options, num_buckets, hash_fn,
3195                 sort_fn, cmp_fn);
3196 }
3197
3198 struct ao2_container *__ao2_container_alloc_list(unsigned int ao2_options,
3199         unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
3200 {
3201         return __ao2_container_alloc_hash(ao2_options, container_options, 1, NULL, sort_fn,
3202                 cmp_fn);
3203 }
3204
3205 struct ao2_container *__ao2_container_alloc_list_debug(unsigned int ao2_options,
3206         unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
3207         const char *tag, const char *file, int line, const char *func, int ref_debug)
3208 {
3209         return __ao2_container_alloc_hash_debug(ao2_options, container_options, 1, NULL,
3210                 sort_fn, cmp_fn, tag, file, line, func, ref_debug);
3211 }
3212
3213 /*!
3214  * A structure to hold the object held by the container and
3215  * where it is located in it.
3216  *
3217  * A red-black tree has the following properties:
3218  *
3219  * 1) Every node is either black or red.
3220  *
3221  * 2) The root is black.
3222  *
3223  * 3) If a node has a NULL child, that "child" is considered
3224  * black.
3225  *
3226  * 4) If a node is red, then both of its children are black.
3227  *
3228  * 5) Every path from a node to a descendant NULL child has the
3229  * same number of black nodes.  (Including the black NULL
3230  * child.)
3231  */
3232 struct rbtree_node {
3233         /*!
3234          * \brief Items common to all container nodes.
3235          * \note Must be first in the specific node struct.
3236          */
3237         struct ao2_container_node common;
3238         /*! Parent node of this node. NULL if this is the root node. */
3239         struct rbtree_node *parent;
3240         /*! Left child node of this node.  NULL if does not have this child. */
3241         struct rbtree_node *left;
3242         /*! Right child node of this node.  NULL if does not have this child. */
3243         struct rbtree_node *right;
3244         /*! TRUE if the node is red. */
3245         unsigned int is_red:1;
3246 };
3247
3248 /*!
3249  * A rbtree container in addition to values common to all
3250  * container types, stores the pointer to the root node of the
3251  * tree.
3252  */
3253 struct ao2_container_rbtree {
3254         /*!
3255          * \brief Items common to all containers.
3256          * \note Must be first in the specific container struct.
3257          */
3258         struct ao2_container common;
3259         /*! Root node of the tree.  NULL if the tree is empty. */
3260         struct rbtree_node *root;
3261 #if defined(AST_DEVMODE)
3262         struct {
3263                 /*! Fixup insert left cases 1-3 */
3264                 int fixup_insert_left[3];
3265                 /*! Fixup insert right cases 1-3 */
3266                 int fixup_insert_right[3];
3267                 /*! Fixup delete left cases 1-4 */
3268                 int fixup_delete_left[4];
3269                 /*! Fixup delete right cases 1-4 */
3270                 int fixup_delete_right[4];
3271                 /*! Deletion of node with number of children (0-2). */
3272                 int delete_children[3];
3273         } stats;
3274 #endif  /* defined(AST_DEVMODE) */
3275 };
3276
3277 /*!
3278  * \internal
3279  * \brief Get the most left node in the tree.
3280  * \since 12.0.0
3281  *
3282  * \param node Starting node to find the most left node.
3283  *
3284  * \return Left most node.  Never NULL.
3285  */
3286 static struct rbtree_node *rb_node_most_left(struct rbtree_node *node)
3287 {
3288         while (node->left) {
3289                 node = node->left;
3290         }
3291
3292         return node;
3293 }
3294
3295 /*!
3296  * \internal
3297  * \brief Get the most right node in the tree.
3298  * \since 12.0.0
3299  *
3300  * \param node Starting node to find the most right node.
3301  *
3302  * \return Right most node.  Never NULL.
3303  */
3304 static struct rbtree_node *rb_node_most_right(struct rbtree_node *node)
3305 {
3306         while (node->right) {
3307                 node = node->right;
3308         }
3309
3310         return node;
3311 }
3312
3313 /*!
3314  * \internal
3315  * \brief Get the next node in ascending sequence.
3316  * \since 12.0.0
3317  *
3318  * \param node Starting node to find the next node.
3319  *
3320  * \retval node on success.
3321  * \retval NULL if no node.
3322  */
3323 static struct rbtree_node *rb_node_next(struct rbtree_node *node)
3324 {
3325         if (node->right) {
3326                 return rb_node_most_left(node->right);
3327         }
3328
3329         /* Find the parent that the node is a left child of. */
3330         while (node->parent) {
3331                 if (node->parent->left == node) {
3332                         /* We are the left child.  The parent is the next node. */
3333                         return node->parent;
3334                 }
3335                 node = node->parent;
3336         }
3337         return NULL;
3338 }
3339
3340 /*!
3341  * \internal
3342  * \brief Get the next node in descending sequence.
3343  * \since 12.0.0
3344  *
3345  * \param node Starting node to find the previous node.
3346  *
3347  * \retval node on success.
3348  * \retval NULL if no node.
3349  */
3350 static struct rbtree_node *rb_node_prev(struct rbtree_node *node)
3351 {
3352         if (node->left) {
3353                 return rb_node_most_right(node->left);
3354         }
3355
3356         /* Find the parent that the node is a right child of. */
3357         while (node->parent) {
3358                 if (node->parent->right == node) {
3359                         /* We are the right child.  The parent is the previous node. */
3360                         return node->parent;
3361                 }
3362                 node = node->parent;
3363         }
3364         return NULL;
3365 }
3366
3367 /*!
3368  * \internal
3369  * \brief Get the next node in pre-order sequence.
3370  * \since 12.0.0
3371  *
3372  * \param node Starting node to find the next node.
3373  *
3374  * \retval node on success.
3375  * \retval NULL if no node.
3376  */
3377 static struct rbtree_node *rb_node_pre(struct rbtree_node *node)
3378 {
3379         /* Visit the children if the node has any. */
3380         if (node->left) {
3381                 return node->left;
3382         }
3383         if (node->right) {
3384                 return node->right;
3385         }
3386
3387         /* Time to go back up. */
3388         for (;;) {
3389                 if (!node->parent) {
3390                         return NULL;
3391                 }
3392                 if (node->parent->left == node && node->parent->right) {
3393                         /*
3394                          * We came up the left child and there's a right child.  Visit
3395                          * it.
3396                          */
3397                         return node->parent->right;
3398                 }
3399                 node = node->parent;
3400         }
3401 }
3402
3403 /*!
3404  * \internal
3405  * \brief Get the next node in post-order sequence.
3406  * \since 12.0.0
3407  *
3408  * \param node Starting node to find the next node.
3409  *
3410  * \retval node on success.
3411  * \retval NULL if no node.
3412  */
3413 static struct rbtree_node *rb_node_post(struct rbtree_node *node)
3414 {
3415         /* This node's children have already been visited. */
3416         for (;;) {
3417                 if (!node->parent) {
3418                         return NULL;
3419                 }
3420                 if (node->parent->left == node) {
3421                         /* We came up the left child. */
3422                         node = node->parent;
3423
3424                         /*
3425                          * Find the right child's left most childless node.
3426                          */
3427                         while (node->right) {
3428                                 node = rb_node_most_left(node->right);
3429                         }
3430
3431                         /*
3432                          * This node's left child has already been visited or it doesn't
3433                          * have any children.
3434                          */
3435                         return node;
3436                 }
3437
3438                 /*
3439                  * We came up the right child.
3440                  *
3441                  * This node's children have already been visited.  Time to
3442                  * visit the parent.
3443                  */
3444                 return node->parent;
3445         }
3446 }
3447
3448 /*!
3449  * \internal
3450  * \brief Get the next non-empty node in ascending sequence.
3451  * \since 12.0.0
3452  *
3453  * \param node Starting node to find the next node.
3454  *
3455  * \retval node on success.
3456  * \retval NULL if no node.
3457  */
3458 static struct rbtree_node *rb_node_next_full(struct rbtree_node *node)
3459 {
3460         for (;;) {
3461                 node = rb_node_next(node);
3462                 if (!node || node->common.obj) {
3463                         return node;
3464                 }
3465         }
3466 }
3467
3468 /*!
3469  * \internal
3470  * \brief Get the next non-empty node in descending sequence.
3471  * \since 12.0.0
3472  *
3473  * \param node Starting node to find the previous node.
3474  *
3475  * \retval node on success.
3476  * \retval NULL if no node.
3477  */
3478 static struct rbtree_node *rb_node_prev_full(struct rbtree_node *node)
3479 {
3480         for (;;) {
3481                 node = rb_node_prev(node);
3482                 if (!node || node->common.obj) {
3483                         return node;
3484                 }
3485         }
3486 }
3487
3488 enum equal_node_bias {
3489         /*! Bias search toward first matching node in the container. */
3490         BIAS_FIRST,
3491         /*! Bias search toward any matching node. */
3492         BIAS_EQUAL,
3493         /*! Bias search toward last matching node in the container. */
3494         BIAS_LAST,
3495 };
3496
3497 enum empty_node_direction {
3498         GO_LEFT,
3499         GO_RIGHT,
3500 };
3501
3502 /*!
3503  * \internal
3504  * \brief Determine which way to go from an empty node.
3505  * \since 12.0.0
3506  *
3507  * \param empty Empty node to determine which side obj_right goes on.
3508  * \param sort_fn Sort comparison function for non-empty nodes.
3509  * \param obj_right pointer to the (user-defined part) of an object.
3510  * \param flags flags from ao2_callback()
3511  *   OBJ_POINTER - if set, 'obj_right', is an object.
3512  *   OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
3513  *   OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
3514  * \param bias How to bias search direction for duplicates
3515  *
3516  * \return enum empty_node_direction to proceed.
3517  */
3518 static enum empty_node_direction rb_find_empty_direction(struct rbtree_node *empty, ao2_sort_fn *sort_fn, void *obj_right, enum search_flags flags, enum equal_node_bias bias)
3519 {
3520         int cmp;
3521         struct rbtree_node *cur;
3522         struct rbtree_node *right_most;
3523
3524         /* Try for a quick definite go left. */
3525         if (!empty->left) {
3526                 /* The empty node has no left child. */
3527                 return GO_RIGHT;
3528         }
3529         right_most = rb_node_most_right(empty->left);
3530         if (right_most->common.obj) {
3531                 cmp = sort_fn(right_most->common.obj, obj_right, flags);
3532                 if (cmp < 0) {
3533                         return GO_RIGHT;
3534                 }
3535                 if (cmp == 0 && bias == BIAS_LAST) {
3536                         return GO_RIGHT;
3537                 }
3538                 return GO_LEFT;
3539         }
3540
3541         /* Try for a quick definite go right. */
3542         if (!empty->right) {
3543                 /* The empty node has no right child. */
3544                 return GO_LEFT;
3545         }
3546         cur = rb_node_most_left(empty->right);
3547         if (cur->common.obj) {
3548                 cmp = sort_fn(cur->common.obj, obj_right, flags);
3549                 if (cmp > 0) {
3550                         return GO_LEFT;
3551                 }
3552                 if (cmp == 0 && bias == BIAS_FIRST) {
3553                         return GO_LEFT;
3554                 }
3555                 return GO_RIGHT;
3556         }
3557
3558         /*
3559          * Have to scan the previous nodes from the right_most node of
3560          * the left subtree for the first non-empty node to determine
3561          * direction.
3562          */
3563         cur = right_most;
3564         for (;;) {
3565                 /* Find previous node. */
3566                 if (cur->left) {
3567                         cur = rb_node_most_right(cur->left);
3568                 } else {
3569                         /* Find the parent that the node is a right child of. */
3570                         for (;;) {
3571                                 if (cur->parent == empty) {
3572                                         /* The left side of the empty node is all empty nodes. */
3573                                         return GO_RIGHT;
3574                                 }
3575                                 if (cur->parent->right == cur) {
3576                                         /* We are the right child.  The parent is the previous node. */
3577                                         cur = cur->parent;
3578                                         break;
3579                                 }
3580                                 cur = cur->parent;
3581                         }
3582                 }
3583
3584                 if (cur->common.obj) {
3585                         cmp = sort_fn(cur->common.obj, obj_right, flags);
3586                         if (cmp < 0) {
3587                                 return GO_RIGHT;
3588                         }
3589                         if (cmp == 0 && bias == BIAS_LAST) {
3590                                 return GO_RIGHT;
3591                         }
3592                         return GO_LEFT;
3593                 }
3594         }
3595 }
3596
3597 /*!
3598  * \internal
3599  * \brief Tree node rotation left.
3600  * \since 12.0.0
3601  *
3602  * \param self Container holding node.
3603  * \param node Node to perform a left rotation with.
3604  *
3605  *        p                         p
3606  *        |     Left rotation       |
3607  *        N        --->             Ch
3608  *       / \                       / \
3609  *      a  Ch                     N   c
3610  *        / \                    / \
3611  *       b   c                  a   b
3612  *
3613  * N = node
3614  * Ch = child
3615  * p = parent
3616  * a,b,c = other nodes that are unaffected by the rotation.
3617  *
3618  * \note It is assumed that the node's right child exists.
3619  *
3620  * \return Nothing
3621  */
3622 static void rb_rotate_left(struct ao2_container_rbtree *self, struct rbtree_node *node)
3623 {
3624         struct rbtree_node *child;      /*!< Node's right child. */
3625
3626         child = node->right;
3627
3628         /* Link the node's parent to the child. */
3629         if (!node->parent) {
3630                 /* Node is the root so we get a new root node. */
3631                 self->root = child;
3632         } else if (node->parent->left == node) {
3633                 /* Node is a left child. */
3634                 node->parent->left = child;
3635         } else {
3636                 /* Node is a right child. */
3637                 node->parent->right = child;
3638         }
3639         child->parent = node->parent;
3640
3641         /* Link node's right subtree to the child's left subtree. */
3642         node->right = child->left;
3643         if (node->right) {
3644                 node->right->parent = node;
3645         }
3646
3647         /* Link the node to the child's left. */
3648         node->parent = child;
3649         child->left = node;
3650 }
3651
3652 /*!
3653  * \internal
3654  * \brief Tree node rotation right.
3655  * \since 12.0.0
3656  *
3657  * \param self Container holding node.
3658  * \param node Node to perform a right rotation with.
3659  *
3660  *        p                         p
3661  *        |     Right rotation      |
3662  *        Ch                        N
3663  *       / \       <---            / \
3664  *      a  N                      Ch  c
3665  *        / \                    / \
3666  *       b   c                  a   b
3667  *
3668  * N = node
3669  * Ch = child
3670  * p = parent
3671  * a,b,c = other nodes that are unaffected by the rotation.
3672  *
3673  * \note It is assumed that the node's left child exists.
3674  *
3675  * \return Nothing
3676  */
3677 static void rb_rotate_right(struct ao2_container_rbtree *self, struct rbtree_node *node)
3678 {
3679         struct rbtree_node *child;      /*!< Node's left child. */
3680
3681         child = node->left;
3682
3683         /* Link the node's parent to the child. */
3684         if (!node->parent) {
3685                 /* Node is the root so we get a new root node. */
3686                 self->root = child;
3687         } else if (node->parent->right == node) {
3688                 /* Node is a right child. */
3689                 node->parent->right = child;
3690         } else {
3691                 /* Node is a left child. */
3692                 node->parent->left = child;
3693         }
3694         child->parent = node->parent;
3695
3696         /* Link node's left subtree to the child's right subtree. */
3697         node->left = child->right;
3698         if (node->left) {
3699                 node->left->parent = node;
3700         }
3701
3702         /* Link the node to the child's right. */
3703         node->parent = child;
3704         child->right = node;
3705 }
3706
3707 /*!
3708  * \internal
3709  * \brief Create an empty copy of this container.
3710  * \since 12.0.0
3711  *
3712  * \param self Container to operate upon.
3713  *
3714  * \retval empty-clone-container on success.
3715  * \retval NULL on error.
3716  */
3717 static struct ao2_container *rb_ao2_alloc_empty_clone(struct ao2_container_rbtree *self)
3718 {
3719         struct astobj2 *orig_obj;
3720         unsigned int ao2_options;
3721
3722         /* Get container ao2 options. */
3723         orig_obj = INTERNAL_OBJ(self);