Review Board 1.7.16


Add ability to clone ao2 containers.

Review Request #1746 - Created Feb. 15, 2012 and submitted

rmudgett
trunk
Reviewers
asterisk-dev
Asterisk
Occasionally there is a need to put all objects in one container also into another container.

Some reasons you might need to do this:
1) You need to reconfigure a container.   You would do this by creating a new container with the new configuration and ao2_container_dup the old container into it.  Then replace the old container with the new.  Then destroy the old container.

2) You need the contents of a container to remain stable while operating on all of the objects.  You would do this by creating a cloned container of the original with ao2_container_clone.  The cloned container is a snapshot of the objects at the time of the cloning.  When done, just destroy the cloned container.
Added unit testing code to test the new ao2_container_clone and ao2_container_dup functions.

Tests still pass.

Changes between revision 2 and 3

1 2 3 4
1 2 3 4

  1. /trunk/include/asterisk/astobj2.h: Loading...
  2. /trunk/main/astobj2.c: Loading...
  3. /trunk/tests/test_astobj2.c: Loading...
/trunk/include/asterisk/astobj2.h
Diff Revision 2 Diff Revision 3
[20] 206 lines
[+20] [+] were called to appear in /tmp/refs, you can do this sort of thing:
207
#ifdef REF_DEBUG
207
#ifdef REF_DEBUG
208
#define dialog_ref(arg1,arg2) dialog_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
208
#define dialog_ref(arg1,arg2) dialog_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
209
#define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
209
#define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
210
static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
210
static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
211
{
211
{
212
	if (p)
212
	if (p) {
213
		ao2_ref_debug(p, 1, tag, file, line, func);
213
		ao2_ref_debug(p, 1, tag, file, line, func);
214
	else
214
	} else {
215
		ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
215
		ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");

    
   
216
	}
216
	return p;
217
	return p;
217
}
218
}
218

    
   
219

   
219
static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
220
static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
220
{
221
{
221
	if (p)
222
	if (p) {
222
		ao2_ref_debug(p, -1, tag, file, line, func);
223
		ao2_ref_debug(p, -1, tag, file, line, func);

    
   
224
	}
223
	return NULL;
225
	return NULL;
224
}
226
}
225
#else
227
#else
226
static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag)
228
static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag)
227
{
229
{
228
	if (p)
230
	if (p) {
229
		ao2_ref(p, 1);
231
		ao2_ref(p, 1);
230
	else
232
	} else {
231
		ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
233
		ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");

    
   
234
	}
232
	return p;
235
	return p;
233
}
236
}
234

    
   
237

   
235
static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag)
238
static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag)
236
{
239
{
237
	if (p)
240
	if (p) {
238
		ao2_ref(p, -1);
241
		ao2_ref(p, -1);

    
   
242
	}
239
	return NULL;
243
	return NULL;
240
}
244
}
241
#endif
245
#endif
242

    
   
246

   
243
In the above code, note that the "normal" helper funcs call ao2_ref() as
247
In the above code, note that the "normal" helper funcs call ao2_ref() as
[+20] [20] 86 lines
[+20] [+] Example:
330

    
   
334

   
331
	ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
335
	ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
332

    
   
336

   
333
	*//* Unlink us from the owner (channel) if we have one *//*
337
	*//* Unlink us from the owner (channel) if we have one *//*
334
	if (dialog->owner) {
338
	if (dialog->owner) {
335
		if (lockowner)
339
		if (lockowner) {
336
			ast_channel_lock(dialog->owner);
340
			ast_channel_lock(dialog->owner);

    
   
341
		}
337
		ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
342
		ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
338
		dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
343
		dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
339
		if (lockowner)
344
		if (lockowner) {
340
			ast_channel_unlock(dialog->owner);
345
			ast_channel_unlock(dialog->owner);
341
	}
346
		}

    
   
347
	}
342
	if (dialog->registry) {
348
	if (dialog->registry) {
343
		if (dialog->registry->call == dialog)
349
		if (dialog->registry->call == dialog) {
344
			dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
350
			dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");

    
   
351
		}
345
		dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
352
		dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
346
	}
353
	}
347
    ...
354
	...
348
 	dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
355
 	dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
349

    
   
356

   
[+20] [20] 32 lines
[+20] [+] murf
382
 * data of the object.
389
 * data of the object.
383
 */
390
 */
384
typedef void (*ao2_destructor_fn)(void *);
391
typedef void (*ao2_destructor_fn)(void *);
385

    
   
392

   
386

    
   
393

   
387
/*! \brief
394
/*!
388
 * Allocate and initialize an object.
395
 * \brief Allocate and initialize an object.
389
 *
396
 *
390
 * \param data_size The sizeof() of the user-defined structure.
397
 * \param data_size The sizeof() of the user-defined structure.
391
 * \param destructor_fn The destructor function (can be NULL)
398
 * \param destructor_fn The destructor function (can be NULL)
392
 * \param debug_msg
399
 * \param debug_msg Ao2 object debug tracing message.
393
 * \return A pointer to user-data.
400
 * \return A pointer to user-data.
394
 *
401
 *

    
   
402
 * \details
395
 * Allocates a struct astobj2 with sufficient space for the
403
 * Allocates a struct astobj2 with sufficient space for the
396
 * user-defined structure.
404
 * user-defined structure.
397
 * \note
405
 * \note
398
 * - storage is zeroed; XXX maybe we want a flag to enable/disable this.
406
 * - storage is zeroed; XXX maybe we want a flag to enable/disable this.
399
 * - the refcount of the object just created is 1
407
 * - the refcount of the object just created is 1
400
 * - the returned pointer cannot be free()'d or realloc()'ed;
408
 * - the returned pointer cannot be free()'d or realloc()'ed;
401
 *   rather, we just call ao2_ref(o, -1);
409
 *   rather, we just call ao2_ref(o, -1);
402
 *
410
 *
403
 * @{
411
 * @{
404
 */
412
 */
405

    
   
413

   
406
#if defined(REF_DEBUG)
414
#if defined(REF_DEBUG)
407

    
   
415

   
408
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
416
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
409
#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
417
	__ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)

    
   
418
#define ao2_alloc(data_size, destructor_fn) \

    
   
419
	__ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
410

    
   
420

   
411
#elif defined(__AST_DEBUG_MALLOC)
421
#elif defined(__AST_DEBUG_MALLOC)
412

    
   
422

   
413
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
423
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
414
#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
424
	__ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)

    
   
425
#define ao2_alloc(data_size, destructor_fn) \

    
   
426
	__ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
415

    
   
427

   
416
#else
428
#else
417

    
   
429

   
418
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc((data_size), (destructor_fn))
430
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
419
#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc((data_size), (destructor_fn))
431
	__ao2_alloc((data_size), (destructor_fn))

    
   
432
#define ao2_alloc(data_size, destructor_fn) \

    
   
433
	__ao2_alloc((data_size), (destructor_fn))
420

    
   
434

   
421
#endif
435
#endif
422

    
   
436

   
423
void *__ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, const char *tag,
437
void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, const char *tag,
424
			const char *file, int line, const char *funcname, int ref_debug);
438
	const char *file, int line, const char *funcname, int ref_debug);
425
void *__ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn);
439
void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn);
426

    
   
440

   
427
/*! @} */
441
/*! @} */
428

    
   
442

   
429
/*! \brief
443
/*! \brief
430
 * Reference/unreference an object and return the old refcount.
444
 * Reference/unreference an object and return the old refcount.
[+20] [20] 62 lines
[+20] [+] int __ao2_unlock(void *a, const char *file, const char *func, int line, const char *var);
493
 */
507
 */
494
int __ao2_trylock(void *a, const char *file, const char *func, int line, const char *var);
508
int __ao2_trylock(void *a, const char *file, const char *func, int line, const char *var);
495
#define ao2_trylock(a) __ao2_trylock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
509
#define ao2_trylock(a) __ao2_trylock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
496

    
   
510

   
497
/*!
511
/*!
498
 * \brief Return the lock address of an object
512
 * \brief Return the mutex lock address of an object
499
 *
513
 *
500
 * \param[in] obj A pointer to the object we want.
514
 * \param[in] obj A pointer to the object we want.
501
 * \return the address of the lock, else NULL.
515
 * \return the address of the mutex lock, else NULL.
502
 *
516
 *
503
 * This function comes in handy mainly for debugging locking
517
 * This function comes in handy mainly for debugging locking
504
 * situations, where the locking trace code reports the
518
 * situations, where the locking trace code reports the
505
 * lock address, this allows you to correlate against
519
 * lock address, this allows you to correlate against
506
 * object address, to match objects to reported locks.
520
 * object address, to match objects to reported locks.
[+20] [20] 23 lines
[+20] [+] Operations on container include:
530
         or CMP_MATCH if they are equal
544
         or CMP_MATCH if they are equal
531
         -The hash function returns an int. The hash function
545
         -The hash function returns an int. The hash function
532
         takes two argument, the object pointer and a flags field,
546
         takes two argument, the object pointer and a flags field,
533

    
   
547

   
534
  -  \b ao2_find(c, arg, flags)
548
  -  \b ao2_find(c, arg, flags)
535
	returns zero or more element matching a given criteria
549
    returns zero or more elements matching a given criteria
536
	(specified as arg). 'c' is the container pointer. Flags
550
    (specified as arg). 'c' is the container pointer. Flags
537
    can be:
551
    can be:
538
	OBJ_UNLINK - to remove the object, once found, from the container.
552
    OBJ_UNLINK - to remove the object, once found, from the container.
539
	OBJ_NODATA - don't return the object if found (no ref count change)
553
    OBJ_NODATA - don't return the object if found (no ref count change)
540
	OBJ_MULTIPLE - don't stop at first match
554
    OBJ_MULTIPLE - don't stop at first match
541
	OBJ_POINTER	- if set, 'arg' is an object pointer, and a hash table
555
    OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table
542
                  search will be done. If not, a traversal is done.
556
                  search will be done. If not, a traversal is done.

    
   
557
    OBJ_KEY - if set, 'arg', is a hashable item that is not an object.

    
   
558
 	          Similar to OBJ_POINTER and mutually exclusive.
543

    
   
559

   
544
  -  \b ao2_callback(c, flags, fn, arg)
560
  -  \b ao2_callback(c, flags, fn, arg)
545
	apply fn(obj, arg) to all objects in the container.
561
    apply fn(obj, arg) to all objects in the container.
546
	Similar to find. fn() can tell when to stop, and
562
    Similar to find. fn() can tell when to stop, and
547
	do anything with the object including unlinking it.
563
    do anything with the object including unlinking it.
548
	  - c is the container;
564
      - c is the container;
549
      - flags can be
565
      - flags can be
550
	     OBJ_UNLINK   - to remove the object, once found, from the container.
566
         OBJ_UNLINK   - to remove the object, once found, from the container.
551
	     OBJ_NODATA   - don't return the object if found (no ref count change)
567
         OBJ_NODATA   - don't return the object if found (no ref count change)
552
	     OBJ_MULTIPLE - don't stop at first match
568
         OBJ_MULTIPLE - don't stop at first match
553
	     OBJ_POINTER  - if set, 'arg' is an object pointer, and a hash table
569
         OBJ_POINTER  - if set, 'arg' is an object pointer, and a hash table
554
                        search will be done. If not, a traversal is done through
570
                        search will be done. If not, a traversal is done through
555
                        all the hash table 'buckets'..
571
                        all the hash table 'buckets'..

    
   
572
         OBJ_KEY      - if set, 'arg', is a hashable item that is not an object.

    
   
573
 	                    Similar to OBJ_POINTER and mutually exclusive.
556
      - fn is a func that returns int, and takes 3 args:
574
      - fn is a func that returns int, and takes 3 args:
557
        (void *obj, void *arg, int flags);
575
        (void *obj, void *arg, int flags);
558
          obj is an object
576
          obj is an object
559
          arg is the same as arg passed into ao2_callback
577
          arg is the same as arg passed into ao2_callback
560
          flags is the same as flags passed into ao2_callback
578
          flags is the same as flags passed into ao2_callback
[+20] [20] 87 lines
[+20] [+] enum _cb_results {
648
 */
666
 */
649
enum search_flags {
667
enum search_flags {
650
	/*! Unlink the object for which the callback function
668
	/*! Unlink the object for which the callback function
651
	 *  returned CMP_MATCH.
669
	 *  returned CMP_MATCH.
652
	 */
670
	 */
653
	OBJ_UNLINK	 = (1 << 0),
671
	OBJ_UNLINK = (1 << 0),
654
	/*! On match, don't return the object hence do not increase
672
	/*! On match, don't return the object hence do not increase
655
	 *  its refcount.
673
	 *  its refcount.
656
	 */
674
	 */
657
	OBJ_NODATA	 = (1 << 1),
675
	OBJ_NODATA = (1 << 1),
658
	/*! Don't stop at the first match in ao2_callback() unless the result of
676
	/*! Don't stop at the first match in ao2_callback() unless the result of
659
	 *  of the callback function == (CMP_STOP | CMP_MATCH).
677
	 *  of the callback function == (CMP_STOP | CMP_MATCH).
660
	 */
678
	 */
661
	OBJ_MULTIPLE = (1 << 2),
679
	OBJ_MULTIPLE = (1 << 2),
662
	/*! obj is an object of the same type as the one being searched for,
680
	/*! obj is an object of the same type as the one being searched for,
663
	 *  so use the object's hash function for optimized searching.
681
	 *  so use the object's hash function for optimized searching.
664
	 *  The search function is unaffected (i.e. use the one passed as
682
	 *  The search function is unaffected (i.e. use the one passed as
665
	 *  argument, or match_by_addr if none specified).
683
	 *  argument, or match_by_addr if none specified).
666
	 */
684
	 */
667
	OBJ_POINTER	 = (1 << 3),
685
	OBJ_POINTER = (1 << 3),
668
	/*! 
686
	/*!
669
	 * \brief Continue if a match is not found in the hashed out bucket
687
	 * \brief Continue if a match is not found in the hashed out bucket
670
	 *
688
	 *
671
	 * This flag is to be used in combination with OBJ_POINTER.  This tells
689
	 * This flag is to be used in combination with OBJ_POINTER.  This tells
672
	 * the ao2_callback() core to keep searching through the rest of the
690
	 * the ao2_callback() core to keep searching through the rest of the
673
	 * buckets if a match is not found in the starting bucket defined by
691
	 * buckets if a match is not found in the starting bucket defined by
674
	 * the hash value on the argument.
692
	 * the hash value on the argument.
675
	 */
693
	 */
676
	OBJ_CONTINUE     = (1 << 4),
694
	OBJ_CONTINUE = (1 << 4),
677
	/*! 
695
	/*!
678
	 * \brief By using this flag, the ao2_container being searched will _NOT_
696
	 * \brief By using this flag, the ao2_container being searched will _NOT_
679
	 * be locked.  Only use this flag if the ao2_container is being protected
697
	 * be locked.  Only use this flag if the ao2_container is being protected
680
	 * by another mechanism other that the internal ao2_lock.
698
	 * by another mechanism other that the internal ao2_lock.
681
	 */
699
	 */
682
	OBJ_NOLOCK     = (1 << 5),
700
	OBJ_NOLOCK = (1 << 5),
683
	/*!
701
	/*!
684
	 * \brief The data is hashable, but is not an object.
702
	 * \brief The data is hashable, but is not an object.
685
	 *
703
	 *

    
   
704
	 * \details
686
	 * This can be used when you want to be able to pass custom data
705
	 * This can be used when you want to be able to pass custom data
687
	 * to a hash function that is not a full object, but perhaps just
706
	 * to the container's stored ao2_hash_fn and ao2_find
688
	 * a string.
707
	 * ao2_callback_fn functions that is not a full object, but

    
   
708
	 * perhaps just a string.
689
	 *
709
	 *
690
	 * \note OBJ_KEY and OBJ_POINTER are mutually exclusive options.
710
	 * \note OBJ_KEY and OBJ_POINTER are mutually exclusive options.
691
	 */
711
	 */
692
	OBJ_KEY        = (1 << 6),
712
	OBJ_KEY = (1 << 6),
693
};
713
};
694

    
   
714

   
695
/*!
715
/*!
696
 * Type of a generic function to generate a hash value from an object.
716
 * Type of a generic function to generate a hash value from an object.
697
 * flags is ignored at the moment. Eventually, it will include the
717
 * flags is ignored at the moment. Eventually, it will include the
[+20] [20] 5 lines
[+20] [+] typedef int (ao2_hash_fn)(const void *obj, const int flags);
703
 * Here start declarations of containers.
723
 * Here start declarations of containers.
704
 */
724
 */
705
/*@{ */
725
/*@{ */
706
struct ao2_container;
726
struct ao2_container;
707

    
   
727

   
708
/*! \brief
728
/*!
709
 * Allocate and initialize a container
729
 * \brief Allocate and initialize a hash container with the desired number of buckets.
710
 * with the desired number of buckets.

   
711
 *
730
 *

    
   
731
 * \details
712
 * We allocate space for a struct astobj_container, struct container
732
 * We allocate space for a struct astobj_container, struct container
713
 * and the buckets[] array.
733
 * and the buckets[] array.
714
 *
734
 *
715
 * \param arg1 Number of buckets for hash
735
 * \param n_buckets Number of buckets for hash
716
 * \param arg2 Pointer to a function computing a hash value.
736
 * \param hash_fn Pointer to a function computing a hash value.
717
 * \param arg3 Pointer to a compare function used by ao2_find. (NULL to match everything)
737
 * \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
718
 * \param arg4 used for debugging.
738
 * \param tag used for debugging.
719
 *
739
 *
720
 * \return A pointer to a struct container.
740
 * \return A pointer to a struct container.
721
 *
741
 *
722
 * \note Destructor is set implicitly.
742
 * \note Destructor is set implicitly.
723
 */
743
 */
724

    
   
744

   
725
#if defined(REF_DEBUG)
745
#if defined(REF_DEBUG)
726

    
   
746

   
727
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
747
#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
728
#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc_debug((arg1), (arg2), (arg3), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
748
	__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)

    
   
749
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \

    
   
750
	__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
729

    
   
751

   
730
#elif defined(__AST_DEBUG_MALLOC)
752
#elif defined(__AST_DEBUG_MALLOC)
731

    
   
753

   
732
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
754
#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
733
#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc_debug((arg1), (arg2), (arg3), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
755
	__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)

    
   
756
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \

    
   
757
	__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
734

    
   
758

   
735
#else
759
#else
736

    
   
760

   
737
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc((arg1), (arg2), (arg3))
761
#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
738
#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc((arg1), (arg2), (arg3))
762
	__ao2_container_alloc((n_buckets), (hash_fn), (cmp_fn))

    
   
763
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \

    
   
764
	__ao2_container_alloc((n_buckets), (hash_fn), (cmp_fn))
739

    
   
765

   
740
#endif
766
#endif
741

    
   
767

   
742
struct ao2_container *__ao2_container_alloc(const unsigned int n_buckets,
768
struct ao2_container *__ao2_container_alloc(unsigned int n_buckets, ao2_hash_fn *hash_fn,
743
					    ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
769
	ao2_callback_fn *cmp_fn);
744
struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets,
770
struct ao2_container *__ao2_container_alloc_debug(unsigned int n_buckets,
745
						  ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
771
	ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
746
						  const char *tag, char *file, int line, const char *funcname,
772
	const char *tag, char *file, int line, const char *funcname, int ref_debug);
747
						  int ref_debug);

   
748

    
   
773

   
749
/*! \brief
774
/*! \brief
750
 * Returns the number of elements in a container.
775
 * Returns the number of elements in a container.
751
 */
776
 */
752
int ao2_container_count(struct ao2_container *c);
777
int ao2_container_count(struct ao2_container *c);
[+20] [20] 9 lines
[+20] struct ao2_container *__ao2_container_alloc(const unsigned int n_buckets, [+] struct ao2_container *__ao2_container_alloc(unsigned int n_buckets, ao2_hash_fn *hash_fn,
762
 *
787
 *
763
 * \note This can potentially be expensive because a malloc is
788
 * \note This can potentially be expensive because a malloc is
764
 * needed for every object in the src container.
789
 * needed for every object in the src container.
765
 *
790
 *
766
 * \retval 0 on success.
791
 * \retval 0 on success.
767
 * \retval -1 on error.
792
 * \retval -1 on error.  The dest container has an incomplete

    
   
793
 * copy of the src container objs.
768
 */
794
 */
769
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags);
795
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags);
770

    
   
796

   
771
/*!
797
/*!
772
 * \brief Create a clone/copy of the given container.
798
 * \brief Create a clone/copy of the given container.
[+20] [20] 38 lines
[+20] [+] struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, char *file, int line, const char *funcname, int ref_debug);
811
/*@{ */
837
/*@{ */
812

    
   
838

   
813
/*!
839
/*!
814
 * \brief Add an object to a container.
840
 * \brief Add an object to a container.
815
 *
841
 *
816
 * \param arg1 the container to operate on.
842
 * \param container The container to operate on.
817
 * \param arg2 the object to be added.
843
 * \param obj The object to be added.
818
 * \param arg3 used for debugging.
844
 * \param tag used for debugging.
819
 *
845
 *
820
 * \retval NULL on errors.
846
 * \retval NULL on errors.
821
 * \retval newobj on success.
847
 * \retval newobj on success.
822
 *
848
 *
823
 * This function inserts an object in a container according its key.
849
 * This function inserts an object in a container according its key.
824
 *
850
 *
825
 * \note Remember to set the key before calling this function.
851
 * \note Remember to set the key before calling this function.
826
 *
852
 *
827
 * \note This function automatically increases the reference count to account
853
 * \note This function automatically increases the reference count to account
828
 *       for the reference that the container now holds to the object.
854
 *       for the reference that the container now holds to the object.
829
 */
855
 */
830
#ifdef REF_DEBUG
856
#ifdef REF_DEBUG
831

    
   
857

   
832
#define ao2_t_link(arg1, arg2, arg3)        __ao2_link_debug((arg1), (arg2), 0, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
858
#define ao2_t_link(container, obj, tag)					__ao2_link_debug((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
833
#define ao2_link(arg1, arg2)                __ao2_link_debug((arg1), (arg2), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
859
#define ao2_link(container, obj)						__ao2_link_debug((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
834
#define ao2_t_link_nolock(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
860

   
835
#define ao2_link_nolock(arg1, arg2)         __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
861
#define ao2_t_link_nolock(container, obj, tag)			__ao2_link_debug((container), (obj), OBJ_NOLOCK, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)

    
   
862
#define ao2_link_nolock(container, obj)					__ao2_link_debug((container), (obj), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
836

    
   
863

   
837
#else
864
#else
838

    
   
865

   
839
#define ao2_t_link(arg1, arg2, arg3)        __ao2_link((arg1), (arg2), 0)
866
#define ao2_t_link(container, obj, tag)					__ao2_link((container), (obj), 0)
840
#define ao2_link(arg1, arg2)                __ao2_link((arg1), (arg2), 0)
867
#define ao2_link(container, obj)						__ao2_link((container), (obj), 0)
841
#define ao2_t_link_nolock(arg1, arg2, arg3) __ao2_link((arg1), (arg2), OBJ_NOLOCK)
868

   
842
#define ao2_link_nolock(arg1, arg2)         __ao2_link((arg1), (arg2), OBJ_NOLOCK)
869
#define ao2_t_link_nolock(container, obj, tag)			__ao2_link((container), (obj), OBJ_NOLOCK)

    
   
870
#define ao2_link_nolock(container, obj)					__ao2_link((container), (obj), OBJ_NOLOCK)
843

    
   
871

   
844
#endif
872
#endif
845

    
   
873

   
846
void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, const char *tag, char *file, int line, const char *funcname);
874
void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, const char *tag, char *file, int line, const char *funcname);
847
void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
875
void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
848

    
   
876

   
849
/*!
877
/*!
850
 * \brief Remove an object from a container
878
 * \brief Remove an object from a container
851
 *
879
 *
852
 * \param arg1 the container
880
 * \param container The container to operate on.
853
 * \param arg2 the object to unlink
881
 * \param obj The object to unlink.
854
 * \param arg3 tag for debugging
882
 * \param tag used for debugging.
855
 *
883
 *
856
 * \retval NULL, always
884
 * \retval NULL, always
857
 *
885
 *
858
 * \note The object requested to be unlinked must be valid.  However, if it turns
886
 * \note The object requested to be unlinked must be valid.  However, if it turns
859
 *       out that it is not in the container, this function is still safe to
887
 *       out that it is not in the container, this function is still safe to
860
 *       be called.
888
 *       be called.
861
 *
889
 *
862
 * \note If the object gets unlinked from the container, the container's
890
 * \note If the object gets unlinked from the container, the container's
863
 *       reference to the object will be automatically released. (The
891
 *       reference to the object will be automatically released. (The
864
 *       refcount will be decremented).
892
 *       refcount will be decremented).
865
 */
893
 */
866
#ifdef REF_DEBUG
894
#ifdef REF_DEBUG
867

    
   
895

   
868
#define ao2_t_unlink(arg1, arg2, arg3)          __ao2_unlink_debug((arg1), (arg2), 0, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
896
#define ao2_t_unlink(container, obj, tag)				__ao2_unlink_debug((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
869
#define ao2_unlink(arg1, arg2)                  __ao2_unlink_debug((arg1), (arg2), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
897
#define ao2_unlink(container, obj)						__ao2_unlink_debug((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
870
#define ao2_t_unlink_nolock(arg1, arg2, arg3)   __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
898

   
871
#define ao2_unlink_nolock(arg1, arg2)           __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
899
#define ao2_t_unlink_nolock(container, obj, tag)		__ao2_unlink_debug((container), (obj), OBJ_NOLOCK, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)

    
   
900
#define ao2_unlink_nolock(container, obj)				__ao2_unlink_debug((container), (obj), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
872

    
   
901

   
873
#else
902
#else
874

    
   
903

   
875
#define ao2_t_unlink(arg1, arg2, arg3)          __ao2_unlink((arg1), (arg2), 0)
904
#define ao2_t_unlink(container, obj, tag)				__ao2_unlink((container), (obj), 0)
876
#define ao2_unlink(arg1, arg2)                  __ao2_unlink((arg1), (arg2), 0)
905
#define ao2_unlink(container, obj)						__ao2_unlink((container), (obj), 0)
877
#define ao2_t_unlink_nolock(arg1, arg2, arg3)   __ao2_unlink((arg1), (arg2), OBJ_NOLOCK)
906

   
878
#define ao2_unlink_nolock(arg1, arg2)           __ao2_unlink((arg1), (arg2), OBJ_NOLOCK)
907
#define ao2_t_unlink_nolock(container, obj, tag)		__ao2_unlink((container), (obj), OBJ_NOLOCK)

    
   
908
#define ao2_unlink_nolock(container, obj)				__ao2_unlink((container), (obj), OBJ_NOLOCK)
879

    
   
909

   
880
#endif
910
#endif
881

    
   
911

   
882
void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, char *file, int line, const char *funcname);
912
void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, char *file, int line, const char *funcname);
883
void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
913
void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
[+20] [20] 5 lines
[+20] void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, char *file, int line, const char *funcname);
889
 * ao2_callback() is a generic function that applies cb_fn() to all objects
919
 * ao2_callback() is a generic function that applies cb_fn() to all objects
890
 * in a container, as described below.
920
 * in a container, as described below.
891
 *
921
 *
892
 * \param c A pointer to the container to operate on.
922
 * \param c A pointer to the container to operate on.
893
 * \param flags A set of flags specifying the operation to perform,
923
 * \param flags A set of flags specifying the operation to perform,
894
	partially used by the container code, but also passed to
924
 *  partially used by the container code, but also passed to
895
	the callback.
925
 *  the callback.
896
     - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts
926
 *   - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts
897
       of any of the traversed objects will be incremented.
927
 *     of any of the traversed objects will be incremented.
898
       On the converse, if it is NOT set (the default), The ref count
928
 *     On the converse, if it is NOT set (the default), The ref count
899
       of each object for which CMP_MATCH was set will be incremented,
929
 *     of each object for which CMP_MATCH was set will be incremented,
900
       and you will have no way of knowing which those are, until
930
 *     and you will have no way of knowing which those are, until
901
       the multiple-object-return functionality is implemented.
931
 *     the multiple-object-return functionality is implemented.
902
     - If OBJ_POINTER is set, the traversed items will be restricted
932
 *   - If OBJ_POINTER is set, the traversed items will be restricted
903
       to the objects in the bucket that the object key hashes to.
933
 *     to the objects in the bucket that the object key hashes to.
904
 * \param cb_fn A function pointer, that will be called on all
934
 * \param cb_fn A function pointer, that will be called on all
905
    objects, to see if they match. This function returns CMP_MATCH
935
 *  objects, to see if they match. This function returns CMP_MATCH
906
    if the object is matches the criteria; CMP_STOP if the traversal
936
 *  if the object is matches the criteria; CMP_STOP if the traversal
907
    should immediately stop, or both (via bitwise ORing), if you find a
937
 *  should immediately stop, or both (via bitwise ORing), if you find a
908
    match and want to end the traversal, and 0 if the object is not a match,
938
 *  match and want to end the traversal, and 0 if the object is not a match,
909
    but the traversal should continue. This is the function that is applied
939
 *  but the traversal should continue. This is the function that is applied
910
    to each object traversed. Its arguments are:
940
 *  to each object traversed. Its arguments are:
911
        (void *obj, void *arg, int flags), where:
941
 *      (void *obj, void *arg, int flags), where:
912
          obj is an object
942
 *        obj is an object
913
          arg is the same as arg passed into ao2_callback
943
 *        arg is the same as arg passed into ao2_callback
914
          flags is the same as flags passed into ao2_callback (flags are
944
 *        flags is the same as flags passed into ao2_callback (flags are
915
           also used by ao2_callback).
945
 *         also used by ao2_callback).
916
 * \param arg passed to the callback.
946
 * \param arg passed to the callback.
917
 * \param tag used for debugging.
947
 * \param tag used for debugging.
918
 * \return when OBJ_MULTIPLE is not included in the flags parameter,
948
 * \return when OBJ_MULTIPLE is not included in the flags parameter,
919
 *         the return value will be either the object found or NULL if no
949
 *         the return value will be either the object found or NULL if no
920
 *         no matching object was found. if OBJ_MULTIPLE is included,
950
 *         no matching object was found. if OBJ_MULTIPLE is included,
[+20] [20] 11 lines
[+20] void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, char *file, int line, const char *funcname);
932
 *   and have OBJ_UNLINK set in flags.
962
 *   and have OBJ_UNLINK set in flags.
933
 * - to look for a specific object in a container; in this case, cb_fn()
963
 * - to look for a specific object in a container; in this case, cb_fn()
934
 *   should not modify the object, but just return a combination of
964
 *   should not modify the object, but just return a combination of
935
 *   CMP_MATCH and CMP_STOP on the desired object.
965
 *   CMP_MATCH and CMP_STOP on the desired object.
936
 * Other usages are also possible, of course.
966
 * Other usages are also possible, of course.
937

    
   
967
 *
938
 * This function searches through a container and performs operations
968
 * This function searches through a container and performs operations
939
 * on objects according on flags passed.
969
 * on objects according on flags passed.
940
 * XXX describe better
970
 * XXX describe better
941
 * The comparison is done calling the compare function set implicitly.
971
 * The comparison is done calling the compare function set implicitly.
942
 * The p pointer can be a pointer to an object or to a key,
972
 * The p pointer can be a pointer to an object or to a key,
943
 * we can say this looking at flags value.
973
 * we can say this looking at flags value.
944
 * If p points to an object we will search for the object pointed
974
 * If p points to an object we will search for the object pointed
945
 * by this value, otherwise we search for a key value.
975
 * by this value, otherwise we search for a key value.
946
 * If the key is not unique we only find the first matching valued.
976
 * If the key is not unique we only find the first matching valued.
947
 *
977
 *
948
 * The use of flags argument is the follow:
978
 * The use of flags argument is the follow:
949
 *
979
 *
950
 *	OBJ_UNLINK 		unlinks the object found
980
 *      OBJ_UNLINK              unlinks the object found
951
 *	OBJ_NODATA		on match, do return an object
981
 *      OBJ_NODATA              on match, do return an object
952
 *				Callbacks use OBJ_NODATA as a default
982
 *                              Callbacks use OBJ_NODATA as a default
953
 *				functions such as find() do
983
 *                              functions such as find() do
954
 *	OBJ_MULTIPLE		return multiple matches
984
 *      OBJ_MULTIPLE            return multiple matches
955
 *				Default is no.
985
 *                              Default is no.
956
 *	OBJ_POINTER 		the pointer is an object pointer
986
 *      OBJ_POINTER             the pointer is an object pointer

    
   
987
 *      OBJ_KEY                 the pointer is to a hashable key
957
 *
988
 *
958
 * \note When the returned object is no longer in use, ao2_ref() should
989
 * \note When the returned object is no longer in use, ao2_ref() should
959
 * be used to free the additional reference possibly created by this function.
990
 * be used to free the additional reference possibly created by this function.
960
 *
991
 *
961
 * @{
992
 * @{
962
 */
993
 */
963
#ifdef REF_DEBUG
994
#ifdef REF_DEBUG
964

    
   
995

   
965
#define ao2_t_callback(c,flags,cb_fn,arg,tag) __ao2_callback_debug((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
996
#define ao2_t_callback(c, flags, cb_fn, arg, tag) \
966
#define ao2_callback(c,flags,cb_fn,arg)       __ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
997
	__ao2_callback_debug((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

    
   
998
#define ao2_callback(c, flags, cb_fn, arg) \

    
   
999
	__ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
967

    
   
1000

   
968
#else
1001
#else
969

    
   
1002

   
970
#define ao2_t_callback(c,flags,cb_fn,arg,tag) __ao2_callback((c), (flags), (cb_fn), (arg))
1003
#define ao2_t_callback(c, flags, cb_fn, arg, tag) \
971
#define ao2_callback(c,flags,cb_fn,arg)       __ao2_callback((c), (flags), (cb_fn), (arg))
1004
	__ao2_callback((c), (flags), (cb_fn), (arg))

    
   
1005
#define ao2_callback(c, flags, cb_fn, arg) \

    
   
1006
	__ao2_callback((c), (flags), (cb_fn), (arg))
972

    
   
1007

   
973
#endif
1008
#endif
974

    
   
1009

   
975
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn,
1010
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
976
			   void *arg, const char *tag, char *file, int line, const char *funcname);
1011
	ao2_callback_fn *cb_fn, void *arg, const char *tag, char *file, int line,

    
   
1012
	const char *funcname);
977
void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
1013
void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
978

    
   
1014

   
979
/*! @} */
1015
/*! @} */
980

    
   
1016

   
981
/*! \brief
1017
/*! \brief
[+20] [20] 11 lines
[+20] void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
993
 *
1029
 *
994
 * \see ao2_callback()
1030
 * \see ao2_callback()
995
 */
1031
 */
996
#ifdef REF_DEBUG
1032
#ifdef REF_DEBUG
997

    
   
1033

   
998
#define ao2_t_callback_data(arg1,arg2,arg3,arg4,arg5,arg6) __ao2_callback_data_debug((arg1), (arg2), (arg3), (arg4), (arg5), (arg6), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1034
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
999
#define ao2_callback_data(arg1,arg2,arg3,arg4,arg5)        __ao2_callback_data_debug((arg1), (arg2), (arg3), (arg4), (arg5), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
1035
	__ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

    
   
1036
#define ao2_callback_data(container, flags, cb_fn, arg, data) \

    
   
1037
	__ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
1000

    
   
1038

   
1001
#else
1039
#else
1002

    
   
1040

   
1003
#define ao2_t_callback_data(arg1,arg2,arg3,arg4,arg5,arg6) __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5))
1041
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
1004
#define ao2_callback_data(arg1,arg2,arg3,arg4,arg5)        __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5))
1042
	__ao2_callback_data((container), (flags), (cb_fn), (arg), (data))

    
   
1043
#define ao2_callback_data(container, flags, cb_fn, arg, data) \

    
   
1044
	__ao2_callback_data((container), (flags), (cb_fn), (arg), (data))
1005

    
   
1045

   
1006
#endif
1046
#endif
1007

    
   
1047

   
1008
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
1048
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
1009
				ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag,
1049
	ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, char *file,
1010
				char *file, int line, const char *funcname);
1050
	int line, const char *funcname);
1011
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
1051
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
1012
			  ao2_callback_data_fn *cb_fn, void *arg, void *data);
1052
	ao2_callback_data_fn *cb_fn, void *arg, void *data);
1013

    
   
1053

   
1014
/*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
1054
/*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
1015
 * XXX possibly change order of arguments ?
1055
 * XXX possibly change order of arguments ?
1016
 */
1056
 */
1017
#ifdef REF_DEBUG
1057
#ifdef REF_DEBUG
1018

    
   
1058

   
1019
#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1059
#define ao2_t_find(container, arg, flags, tag) \
1020
#define ao2_find(arg1,arg2,arg3)        __ao2_find_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
1060
	__ao2_find_debug((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

    
   
1061
#define ao2_find(container, arg, flags) \

    
   
1062
	__ao2_find_debug((container), (arg), (flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
1021

    
   
1063

   
1022
#else
1064
#else
1023

    
   
1065

   
1024
#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find((arg1), (arg2), (arg3))
1066
#define ao2_t_find(container, arg, flags, tag) \
1025
#define ao2_find(arg1,arg2,arg3)        __ao2_find((arg1), (arg2), (arg3))
1067
	__ao2_find((container), (arg), (flags))

    
   
1068
#define ao2_find(container, arg, flags) \

    
   
1069
	__ao2_find((container), (arg), (flags))
1026

    
   
1070

   
1027
#endif
1071
#endif
1028

    
   
1072

   
1029
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag,
1073
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
1030
		       char *file, int line, const char *funcname);
1074
	const char *tag, char *file, int line, const char *funcname);
1031
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags);
1075
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags);
1032

    
   
1076

   
1033
/*! \brief
1077
/*! \brief
1034
 *
1078
 *
1035
 *
1079
 *
[+20] [20] 140 lines
[+20] [+] struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
1176
 */
1220
 */
1177
void ao2_iterator_destroy(struct ao2_iterator *i);
1221
void ao2_iterator_destroy(struct ao2_iterator *i);
1178

    
   
1222

   
1179
#ifdef REF_DEBUG
1223
#ifdef REF_DEBUG
1180

    
   
1224

   
1181
#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next_debug((arg1), (arg2),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
1225
#define ao2_t_iterator_next(iter, tag) __ao2_iterator_next_debug((iter), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
1182
#define ao2_iterator_next(arg1)         __ao2_iterator_next_debug((arg1), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
1226
#define ao2_iterator_next(iter)        __ao2_iterator_next_debug((iter), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
1183

    
   
1227

   
1184
#else
1228
#else
1185

    
   
1229

   
1186
#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next((arg1))
1230
#define ao2_t_iterator_next(iter, tag) __ao2_iterator_next((iter))
1187
#define ao2_iterator_next(arg1)         __ao2_iterator_next((arg1))
1231
#define ao2_iterator_next(iter)        __ao2_iterator_next((iter))
1188

    
   
1232

   
1189
#endif
1233
#endif
1190

    
   
1234

   
1191
void *__ao2_iterator_next_debug(struct ao2_iterator *a, const char *tag, char *file, int line, const char *funcname);
1235
void *__ao2_iterator_next_debug(struct ao2_iterator *a, const char *tag, char *file, int line, const char *funcname);
1192
void *__ao2_iterator_next(struct ao2_iterator *a);
1236
void *__ao2_iterator_next(struct ao2_iterator *a);
1193

    
   
1237

   
1194
/* extra functions */
1238
/* extra functions */
1195
void ao2_bt(void);	/* backtrace */
1239
void ao2_bt(void);	/* backtrace */
1196

    
   
1240

   
1197
#endif /* _ASTERISK_ASTOBJ2_H */
1241
#endif /* _ASTERISK_ASTOBJ2_H */
/trunk/main/astobj2.c
Diff Revision 2 Diff Revision 3
 
/trunk/tests/test_astobj2.c
Diff Revision 2 Diff Revision 3
 
  1. /trunk/include/asterisk/astobj2.h: Loading...
  2. /trunk/main/astobj2.c: Loading...
  3. /trunk/tests/test_astobj2.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.