|  |  | @ -108,6 +108,17 @@ struct astobj2_rwlock { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	void *user_data[0]; |  |  |  | 	void *user_data[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | struct ao2_lockobj_priv { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	void *lock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /* AstObj2 with locking provided by a separate object. */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | struct astobj2_lockobj { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct ao2_lockobj_priv lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct __priv_data priv_data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	void *user_data[0]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #ifdef AO2_DEBUG |  |  |  | #ifdef AO2_DEBUG | 
			
		
	
		
		
			
				
					
					|  |  |  | struct ao2_stats ao2; |  |  |  | struct ao2_stats ao2; | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
	
		
		
			
				
					|  |  | @ -118,6 +129,9 @@ struct ao2_stats ao2; | 
			
		
	
		
		
			
				
					
					|  |  |  | #define INTERNAL_OBJ_RWLOCK(user_data) \ |  |  |  | #define INTERNAL_OBJ_RWLOCK(user_data) \ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock))) |  |  |  | 	((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock))) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #define INTERNAL_OBJ_LOCKOBJ(user_data) \ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	((struct astobj2_lockobj *) (((char *) (user_data)) - sizeof(struct astobj2_lockobj))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define INTERNAL_OBJ(user_data) \ |  |  |  | #define INTERNAL_OBJ(user_data) \ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	(struct astobj2 *) ((char *) user_data - sizeof(struct astobj2)) |  |  |  | 	(struct astobj2 *) ((char *) user_data - sizeof(struct astobj2)) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -187,6 +201,7 @@ int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, co | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); |  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_lock *obj_mutex; |  |  |  | 	struct astobj2_lock *obj_mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int res = 0; |  |  |  | 	int res = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (obj == NULL) { |  |  |  | 	if (obj == NULL) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -231,6 +246,10 @@ int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, co | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: |  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* The ao2 object has no lock. */ |  |  |  | 		/* The ao2 object has no lock. */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		res = __ao2_lock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", |  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", | 
			
		
	
		
		
			
				
					
					|  |  |  | 			user_data); |  |  |  | 			user_data); | 
			
		
	
	
		
		
			
				
					|  |  | @ -245,6 +264,7 @@ int __ao2_unlock(void *user_data, const char *file, const char *func, int line, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); |  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_lock *obj_mutex; |  |  |  | 	struct astobj2_lock *obj_mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int res = 0; |  |  |  | 	int res = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int current_value; |  |  |  | 	int current_value; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -281,6 +301,10 @@ int __ao2_unlock(void *user_data, const char *file, const char *func, int line, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: |  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* The ao2 object has no lock. */ |  |  |  | 		/* The ao2 object has no lock. */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		res = __ao2_unlock(obj_lockobj->lockobj.lock, file, func, line, var); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", |  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", | 
			
		
	
		
		
			
				
					
					|  |  |  | 			user_data); |  |  |  | 			user_data); | 
			
		
	
	
		
		
			
				
					|  |  | @ -295,6 +319,7 @@ int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); |  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_lock *obj_mutex; |  |  |  | 	struct astobj2_lock *obj_mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int res = 0; |  |  |  | 	int res = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (obj == NULL) { |  |  |  | 	if (obj == NULL) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -339,6 +364,10 @@ int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: |  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* The ao2 object has no lock. */ |  |  |  | 		/* The ao2 object has no lock. */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return 0; |  |  |  | 		return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		res = __ao2_trylock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", |  |  |  | 		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n", | 
			
		
	
		
		
			
				
					
					|  |  |  | 			user_data); |  |  |  | 			user_data); | 
			
		
	
	
		
		
			
				
					|  |  | @ -370,6 +399,7 @@ enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj = INTERNAL_OBJ(user_data); |  |  |  | 	struct astobj2 *obj = INTERNAL_OBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	enum ao2_lock_req orig_lock; |  |  |  | 	enum ao2_lock_req orig_lock; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) { |  |  |  | 	switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -400,6 +430,10 @@ enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int | 
			
		
	
		
		
			
				
					
					|  |  |  | 			break; |  |  |  | 			break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		orig_lock = __adjust_lock(obj_lockobj->lockobj.lock, lock_how, keep_stronger); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(LOG_ERROR, "Invalid lock option on ao2 object %p\n", user_data); |  |  |  | 		ast_log(LOG_ERROR, "Invalid lock option on ao2 object %p\n", user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* Fall through */ |  |  |  | 		/* Fall through */ | 
			
		
	
	
		
		
			
				
					|  |  | @ -441,6 +475,7 @@ int __ao2_ref(void *user_data, int delta, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); |  |  |  | 	struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_lock *obj_mutex; |  |  |  | 	struct astobj2_lock *obj_mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int current_value; |  |  |  | 	int current_value; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int ret; |  |  |  | 	int ret; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	void *weakproxy = NULL; |  |  |  | 	void *weakproxy = NULL; | 
			
		
	
	
		
		
			
				
					|  |  | @ -552,6 +587,12 @@ int __ao2_ref(void *user_data, int delta, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: |  |  |  | 	case AO2_ALLOC_OPT_LOCK_NOLOCK: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_free(obj); |  |  |  | 		ast_free(obj); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		ao2_t_ref(obj_lockobj->lockobj.lock, -1, "release lockobj"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		ast_free(obj_lockobj); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(__LOG_ERROR, file, line, func, |  |  |  | 		ast_log(__LOG_ERROR, file, line, func, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			"Invalid lock option on ao2 object %p\n", user_data); |  |  |  | 			"Invalid lock option on ao2 object %p\n", user_data); | 
			
		
	
	
		
		
			
				
					|  |  | @ -581,13 +622,14 @@ void __ao2_cleanup(void *obj) | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, |  |  |  | static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 	const char *tag, const char *file, int line, const char *func) |  |  |  | 	void *lockobj, const char *tag, const char *file, int line, const char *func) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	/* allocation */ |  |  |  | 	/* allocation */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *obj; |  |  |  | 	struct astobj2 *obj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_lock *obj_mutex; |  |  |  | 	struct astobj2_lock *obj_mutex; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2_rwlock *obj_rwlock; |  |  |  | 	struct astobj2_rwlock *obj_rwlock; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct astobj2_lockobj *obj_lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	switch (options & AO2_ALLOC_OPT_LOCK_MASK) { |  |  |  | 	switch (options & AO2_ALLOC_OPT_LOCK_MASK) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	case AO2_ALLOC_OPT_LOCK_MUTEX: |  |  |  | 	case AO2_ALLOC_OPT_LOCK_MUTEX: | 
			
		
	
	
		
		
			
				
					|  |  | @ -626,6 +668,26 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in | 
			
		
	
		
		
			
				
					
					|  |  |  | 			return NULL; |  |  |  | 			return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	case AO2_ALLOC_OPT_LOCK_OBJ: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		lockobj = ao2_t_bump(lockobj, "set lockobj"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!lockobj) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			ast_log(__LOG_ERROR, file, line, func, "AO2_ALLOC_OPT_LOCK_OBJ requires a non-NULL lockobj.\n"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #if defined(__AST_DEBUG_MALLOC) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = __ast_calloc(1, sizeof(*obj_lockobj) + data_size, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj = ast_calloc(1, sizeof(*obj_lockobj) + data_size); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (obj_lockobj == NULL) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			ao2_t_ref(lockobj, -1, "release lockobj for failed alloc"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			return NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj_lockobj->lockobj.lock = lockobj; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		obj = (struct astobj2 *) &obj_lockobj->priv_data; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		break; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	default: |  |  |  | 	default: | 
			
		
	
		
		
			
				
					
					|  |  |  | 		/* Invalid option value. */ |  |  |  | 		/* Invalid option value. */ | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ast_log(__LOG_DEBUG, file, line, func, "Invalid lock option requested\n"); |  |  |  | 		ast_log(__LOG_DEBUG, file, line, func, "Invalid lock option requested\n"); | 
			
		
	
	
		
		
			
				
					|  |  | @ -655,6 +717,19 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return EXTERNAL_OBJ(obj); |  |  |  | 	return EXTERNAL_OBJ(obj); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	const char *tag, const char *file, int line, const char *func) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return internal_ao2_alloc(data_size, destructor_fn, options, NULL, tag, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void *__ao2_alloc_with_lockobj(size_t data_size, ao2_destructor_fn destructor_fn, void *lockobj, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	const char *tag, const char *file, int line, const char *func) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return internal_ao2_alloc(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_OBJ, lockobj, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		tag, file, line, func); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | unsigned int ao2_options_get(void *obj) |  |  |  | unsigned int ao2_options_get(void *obj) | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct astobj2 *orig_obj; |  |  |  | 	struct astobj2 *orig_obj; | 
			
		
	
	
		
		
			
				
					|  |  | 
 |