[Asterisk-code-review] RFC: ao2 reference storage location logging part 2. (asterisk[master])

Corey Farrell asteriskteam at digium.com
Thu Jul 7 19:46:27 CDT 2016


Corey Farrell has uploaded a new change for review.

  https://gerrit.asterisk.org/3161

Change subject: RFC: ao2 reference storage location logging part 2.
......................................................................

RFC: ao2 reference storage location logging part 2.

This contains changes to reduce output of refcounter.py from random
parts of Asterisk.  This is meant as a demo of what can be done with
reference storage location logging.

ASTERISK-26171

Change-Id: Ic66d2e8b4267e86eaeac2fac2f88d83dbcad5bde
---
M channels/chan_iax2.c
M channels/chan_sip.c
M channels/iax2/format_compatibility.c
M channels/iax2/provision.c
M channels/sip/include/dialog.h
M include/asterisk/codec.h
M include/asterisk/format.h
M include/asterisk/format_cache.h
M include/asterisk/format_cap.h
M main/channel_internal_api.c
M main/codec.c
M main/codec_builtin.c
M main/format.c
M main/format_cache.c
M main/format_cap.c
M main/frame.c
M main/rtp_engine.c
M main/stasis.c
M main/stasis_cache.c
M main/stasis_message.c
M main/stasis_message_router.c
M main/threadpool.c
M main/translate.c
23 files changed, 401 insertions(+), 352 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/61/3161/1

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 721da9a..527c49a 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1905,9 +1905,9 @@
 	struct ast_format_cap *cap;
 
 	/* We want to add the formats to the cap in the preferred order */
-	cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&cap, AST_FORMAT_CAP_FLAG_DEFAULT);
 	if (!cap || iax2_codec_pref_to_cap(pref, cap)) {
-		ao2_cleanup(cap);
+		ao2_s_cleanup(&cap);
 		return 1;
 	}
 
@@ -1918,13 +1918,14 @@
 	iax2_codec_pref_remove_missing(pref, *formats);
 
 	for (i = 0; i < ast_format_cap_count(cap); i++) {
-		struct ast_format *fmt = ast_format_cap_get_format(cap, i);
+		struct ast_format *fmt;
 
+		ast_s_format_cap_get_format(&fmt, cap, i);
 		iax2_codec_pref_append(pref, fmt, ast_format_cap_get_format_framing(cap, fmt));
-		ao2_ref(fmt, -1);
+		ao2_s_cleanup(&fmt);
 	}
 
-	ao2_ref(cap, -1);
+	ao2_s_cleanup(&cap);
 
 	return res;
 }
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 4cf3c8e..ab57baa 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1179,10 +1179,8 @@
 static int __sip_autodestruct(const void *data);
 static int update_call_counter(struct sip_pvt *fup, int event);
 static int auto_congest(const void *arg);
-static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method,
-	const char *file, int line, const char *func);
-#define find_call(req, addr, intended_method) \
-	__find_call(req, addr, intended_method, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr,
+	const int intended_method, void *debugstorage);
 
 static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp);
 static int build_path(struct sip_pvt *p, struct sip_peer *peer, struct sip_request *req, const char *pathbuf);
@@ -3310,7 +3308,8 @@
 {
 	struct ast_channel *owner;
 
-	dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
+	/* Bump so it doesn't become dead before we are done */
+	ao2_s_init(&dialog);
 
 	ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
 	ao2_t_unlink(dialogs_needdestroy, dialog, "unlinking dialog_needdestroy via ao2_unlink");
@@ -3355,7 +3354,7 @@
 		do_dialog_unlink_sched_items(dialog);
 	}
 
-	dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
+	ao2_s_cleanup(&dialog);
 }
 
 static void append_history_full(struct sip_pvt *p, const char *fmt, ...)
@@ -4181,9 +4180,7 @@
 {
 	struct sip_pkt *pkt = (void *) vdoomed;
 
-	if (pkt->owner) {
-		dialog_unref(pkt->owner, "Retransmission packet is being destroyed");
-	}
+	ao2_s_cleanup(&pkt->owner);
 	ast_free(pkt->data);
 }
 
@@ -4233,7 +4230,7 @@
 	pkt->seqno = seqno;
 	pkt->is_resp = resp;
 	pkt->is_fatal = fatal;
-	pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
+	ao2_s_set(&pkt->owner, p);
 
 	/* The retransmission list owns a pkt ref */
 	pkt->next = p->packets;
@@ -6699,11 +6696,11 @@
 	p->named_callgroups = ast_unref_namedgroups(p->named_callgroups);
 	p->named_pickupgroups = ast_unref_namedgroups(p->named_pickupgroups);
 
-	ao2_cleanup(p->caps);
-	ao2_cleanup(p->jointcaps);
-	ao2_cleanup(p->peercaps);
-	ao2_cleanup(p->redircaps);
-	ao2_cleanup(p->prefcaps);
+	ao2_s_cleanup(&p->caps);
+	ao2_s_cleanup(&p->jointcaps);
+	ao2_s_cleanup(&p->peercaps);
+	ao2_s_cleanup(&p->redircaps);
+	ao2_s_cleanup(&p->prefcaps);
 
 	ast_rtp_dtls_cfg_free(&p->dtls_cfg);
 
@@ -8692,10 +8689,10 @@
 	({																		\
 		int found = 0;														\
 		typeof((obj)) __removed_obj;										\
-		__removed_obj = ao2_t_callback((container),							\
-			OBJ_UNLINK | OBJ_POINTER, ao2_match_by_addr, (obj), (tag));		\
+		ao2_s_callback(&__removed_obj, (container), OBJ_UNLINK | OBJ_POINTER, \
+			ao2_match_by_addr, (obj), (tag));								\
 		if (__removed_obj) {												\
-			ao2_ref(__removed_obj, -1);										\
+			ao2_s_cleanup(&__removed_obj);									\
 			found = 1;														\
 		}																	\
 		found;																\
@@ -8794,24 +8791,24 @@
  */
 struct sip_pvt *__sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
 				 int useglobal_nat, const int intended_method, struct sip_request *req, ast_callid logger_callid,
-				 const char *file, int line, const char *func)
+				 const char *file, int line, const char *func, void *debugstorage)
 {
 	struct sip_pvt *p;
 
 	p = __ao2_alloc_full(sizeof(*p), sip_pvt_dtor,
 		AO2_ALLOC_OPT_LOCK_MUTEX, "allocate a dialog(pvt) struct",
-		file, line, func, NULL);
+		file, line, func, debugstorage);
 	if (!p) {
 		return NULL;
 	}
 
 	if (ast_string_field_init(p, 512)) {
-		ao2_t_ref(p, -1, "failed to string_field_init, drop p");
+		ao2_ref_full(p, -1, "failed to string_field_init, drop p", debugstorage);
 		return NULL;
 	}
 
 	if (!(p->cc_params = ast_cc_config_params_init())) {
-		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
+		ao2_ref_full(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p", debugstorage);
 		return NULL;
 	}
 
@@ -8819,19 +8816,19 @@
 		sip_pvt_callid_set(p, logger_callid);
 	}
 
-	p->caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-	p->jointcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-	p->peercaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-	p->redircaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
-	p->prefcaps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&p->caps, AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&p->jointcaps, AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&p->peercaps, AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&p->redircaps, AST_FORMAT_CAP_FLAG_DEFAULT);
+	ast_s_format_cap_alloc(&p->prefcaps, AST_FORMAT_CAP_FLAG_DEFAULT);
 
 	if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps || !p->prefcaps) {
-		ao2_cleanup(p->caps);
-		ao2_cleanup(p->jointcaps);
-		ao2_cleanup(p->peercaps);
-		ao2_cleanup(p->redircaps);
-		ao2_cleanup(p->prefcaps);
-		ao2_t_ref(p, -1, "Yuck, couldn't allocate format capabilities. Get rid o' p");
+		ao2_s_cleanup(&p->caps);
+		ao2_s_cleanup(&p->jointcaps);
+		ao2_s_cleanup(&p->peercaps);
+		ao2_s_cleanup(&p->redircaps);
+		ao2_s_cleanup(&p->prefcaps);
+		ao2_ref_full(p, -1, "Yuck, couldn't allocate format capabilities. Get rid o' p", debugstorage);
 		return NULL;
 	}
 
@@ -9194,7 +9191,7 @@
 	logger_callid = original->logger_callid;
 	sip_pvt_unlock(original);
 
-	p = sip_alloc(callid, addr, 1, SIP_INVITE, req, logger_callid);
+	sip_s_alloc(&p, callid, addr, 1, SIP_INVITE, req, logger_callid);
 	if (!p)  {
 		return; /* alloc error */
 	}
@@ -9230,7 +9227,7 @@
 
 	pvt_set_needdestroy(p, "forked request"); /* this dialog will terminate once the BYE is responed to or times out. */
 	sip_pvt_unlock(p);
-	dialog_unref(p, "setup forked invite termination");
+	ao2_s_cleanup(&p);
 }
 
 /*! \internal
@@ -9319,8 +9316,8 @@
  * Returns a reference to the sip_pvt object, remember to give it back once done.
  *     Called by handle_request_do
  */
-static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method,
-	const char *file, int line, const char *func)
+static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr,
+	const int intended_method, void *debugstorage)
 {
 	char totag[128];
 	char fromtag[128];
@@ -9377,8 +9374,8 @@
 		struct sip_pvt tmp_dialog = {
 			.callid = callid,
 		};
-		sip_pvt_ptr = __ao2_find(dialogs, &tmp_dialog, OBJ_POINTER,
-			"find_call in dialogs", file, line, func);
+		sip_pvt_ptr = ao2_find_full(dialogs, &tmp_dialog, OBJ_POINTER,
+			"find_call in dialogs", debugstorage);
 		if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
 			/* Found the call */
 			return sip_pvt_ptr;
@@ -9392,13 +9389,14 @@
 		struct sip_pvt *fork_pvt = NULL;
 		struct match_req_args args = { 0, };
 		int found;
-		struct ao2_iterator *iterator = __ao2_callback(dialogs,
+		struct ao2_iterator *iterator;
+		struct sip_via *via = NULL;
+
+		ao2_s_callback(&iterator, dialogs,
 			OBJ_POINTER | OBJ_MULTIPLE,
 			dialog_find_multiple,
 			&tmp_dialog,
-			"pedantic ao2_find in dialogs",
-			file, line, func);
-		struct sip_via *via = NULL;
+			"pedantic ao2_find in dialogs");
 
 		args.method = req->method;
 		args.callid = NULL; /* we already matched this. */
@@ -9427,7 +9425,7 @@
 		}
 
 		/* Iterate a list of dialogs already matched by Call-id */
-		while (iterator && (sip_pvt_ptr = ao2_iterator_next(iterator))) {
+		while (iterator && (sip_pvt_ptr = __ao2_iterator_next(iterator, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, debugstorage))) {
 			sip_pvt_lock(sip_pvt_ptr);
 			found = match_req_to_dialog(sip_pvt_ptr, &args);
 			sip_pvt_unlock(sip_pvt_ptr);
@@ -9451,8 +9449,7 @@
 				/* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
 			 	* RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
 				transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
-				__ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search.",
-					file, line, func);
+				ao2_ref_full(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search.", debugstorage);
 				ao2_iterator_destroy(iterator);
 				dialog_unref(fork_pvt, "unref fork_pvt");
 				free_via(via);
@@ -9463,8 +9460,7 @@
 				/* fall through */
 			case SIP_REQ_NOT_MATCH:
 			default:
-				__ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search",
-					file, line, func);
+				ao2_ref_full(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search", debugstorage);
 				break;
 			}
 		}
@@ -9498,7 +9494,10 @@
 		}
 
 		/* Ok, time to create a new SIP dialog object, a pvt */
-		if (!(p = sip_alloc(callid, addr, 1, intended_method, req, logger_callid)))  {
+		//sip_s_alloc(&p, callid, addr, 1, intended_method, req, logger_callid);
+		p = __sip_alloc(callid, addr, 1, intended_method, req, logger_callid,
+			__FILE__, __LINE__, __PRETTY_FUNCTION__, debugstorage);
+		if (!p)  {
 			/* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
 				getting a dialog from sip_alloc.
 
@@ -9616,14 +9615,16 @@
 		}
 	}
 
-	if (!(mwi = ao2_t_alloc(sizeof(*mwi), sip_subscribe_mwi_destroy, "allocate an mwi struct"))) {
+	mwi = ao2_alloc_full(sizeof(*mwi), sip_subscribe_mwi_destroy, AO2_ALLOC_OPT_LOCK_MUTEX,
+		"allocate an mwi struct", &mwi);
+	if (!mwi) {
 		return -1;
 	}
 
 	mwi->resub = -1;
 
 	if (ast_string_field_init(mwi, 256)) {
-		ao2_t_ref(mwi, -1, "failed to string_field_init, drop mwi");
+		ao2_s_cleanup(&mwi);
 		return -1;
 	}
 
@@ -9640,7 +9641,7 @@
 	mwi->transport = transport;
 
 	ao2_t_link(subscription_mwi_list, mwi, "link new mwi object");
-	ao2_t_ref(mwi, -1, "unref to match ao2_t_alloc");
+	ao2_s_cleanup(&mwi);
 
 	return 0;
 }
@@ -14436,7 +14437,8 @@
 
 	epa_entry->publish_type = publish_type;
 
-	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_PUBLISH, NULL, 0))) {
+	sip_s_alloc(&pvt, NULL, NULL, 0, SIP_PUBLISH, NULL, 0);
+	if (!pvt) {
 		return -1;
 	}
 
@@ -14815,7 +14817,8 @@
 	}
 
 	/* Create a dialog that we will use for the subscription */
-	if (!(mwi->call = sip_alloc(NULL, NULL, 0, SIP_SUBSCRIBE, NULL, 0))) {
+	sip_s_alloc(&mwi->call, NULL, NULL, 0, SIP_SUBSCRIBE, NULL, 0);
+	if (!mwi->call) {
 		return -1;
 	}
 
@@ -15394,7 +15397,8 @@
 		channame += 4;
 	}
 
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
+	sip_s_alloc(&p, NULL, NULL, 0, SIP_NOTIFY, NULL, 0);
+	if (!p) {
 		astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
 		return 0;
 	}
@@ -15402,8 +15406,7 @@
 	if (create_addr(p, channame, NULL, 0)) {
 		/* Maybe they're not registered, etc. */
 		dialog_unlink_all(p);
-		dialog_unref(p, "unref dialog inside for loop" );
-		/* sip_destroy(p); */
+		ao2_s_cleanup(&p);
 		astman_send_error(s, m, "Could not create address");
 		return 0;
 	}
@@ -15435,7 +15438,7 @@
 
 	sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
 	transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
-	dialog_unref(p, "bump down the count of p since we're done with it.");
+	ao2_s_cleanup(&p);
 
 	astman_send_ack(s, m, "Notify Sent");
 	ast_variables_destroy(vars);
@@ -15844,7 +15847,7 @@
 			ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
 			return 0;
 		} else {
-			p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
+			ao2_s_set(&p, r->call);
 			ast_string_field_set(p, theirtag, NULL);	/* forget their old tag, so we don't match tags when getting response */
 		}
 	} else {
@@ -15855,7 +15858,8 @@
 			r->callid_valid = TRUE;
 		}
 		/* Allocate SIP dialog for registration */
-		if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL, 0))) {
+		sip_s_alloc(&p, r->callid, NULL, 0, SIP_REGISTER, NULL, 0);
+		if (!p) {
 			ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
 			return 0;
 		}
@@ -15892,7 +15896,7 @@
 			/* we have what we hope is a temporary network error,
 			 * probably DNS.  We need to reschedule a registration try */
 			dialog_unlink_all(p);
-			p = dialog_unref(p, "unref dialog after unlink_all");
+			ao2_s_cleanup(&p);
 			ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n",
 				r->username, r->hostname, global_reg_timeout);
 			start_register_timeout(r);
@@ -16037,7 +16041,7 @@
 	r->regattempts++;	/* Another attempt */
 	ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
 	res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
-	dialog_unref(p, "p is finished here at the end of transmit_register");
+	ao2_s_cleanup(&p);
 	return res;
 }
 
@@ -19096,11 +19100,15 @@
 		if (ast_format_cap_count(p->peercaps)) {
 			struct ast_format_cap *joint;
 
-			joint = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+			ast_s_format_cap_alloc(&joint, AST_FORMAT_CAP_FLAG_DEFAULT);
 			if (joint) {
 				ast_format_cap_get_compatible(p->jointcaps, p->peercaps, joint);
-				ao2_ref(p->jointcaps, -1);
+				ao2_s_cleanup(&p->jointcaps);
 				p->jointcaps = joint;
+				if (ast_opt_ref_debug) {
+					/* no-op unless we're in REF_DEBUG. */
+					ao2_ref_move(joint, "", &p->jointcaps, &joint);
+				}
 			}
 		}
 		p->maxcallbitrate = peer->maxcallbitrate;
@@ -22481,7 +22489,8 @@
 		char buf[512];
 		struct ast_variable *header, *var;
 
-		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
+		sip_s_alloc(&p, NULL, NULL, 0, SIP_NOTIFY, NULL, 0);
+		if (!p) {
 			ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
 			return CLI_FAILURE;
 		}
@@ -22489,8 +22498,7 @@
 		if (create_addr(p, a->argv[i], NULL, 1)) {
 			/* Maybe they're not registered, etc. */
 			dialog_unlink_all(p);
-			dialog_unref(p, "unref dialog inside for loop" );
-			/* sip_destroy(p); */
+			ao2_s_cleanup(&p);
 			ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
 			continue;
 		}
@@ -22525,7 +22533,7 @@
 		ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
 		sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
 		transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
-		dialog_unref(p, "bump down the count of p since we're done with it.");
+		ao2_s_cleanup(&p);
 	}
 
 	return CLI_SUCCESS;
@@ -27330,7 +27338,8 @@
 	struct ast_msg_var_iterator *iter;
 	struct sip_peer *peer_ptr;
 
-	if (!(pvt = sip_alloc(NULL, NULL, 0, SIP_MESSAGE, NULL, 0))) {
+	sip_s_alloc(&pvt, NULL, NULL, 0, SIP_MESSAGE, NULL, 0);
+	if (!pvt) {
 		return -1;
 	}
 
@@ -27351,7 +27360,7 @@
 	if (ast_strlen_zero(to_host)) {
 		ast_log(LOG_WARNING, "MESSAGE(to) is invalid for SIP - '%s'\n", to);
 		dialog_unlink_all(pvt);
-		dialog_unref(pvt, "MESSAGE(to) is invalid for SIP");
+		ao2_s_cleanup(&pvt);
 		return -1;
 	}
 
@@ -27403,7 +27412,7 @@
 	if (create_addr(pvt, to_host, NULL, TRUE)) {
 		sip_pvt_unlock(pvt);
 		dialog_unlink_all(pvt);
-		dialog_unref(pvt, "create_addr failed sending a MESSAGE");
+		ao2_s_cleanup(&pvt);
 		return -1;
 	}
 
@@ -27426,7 +27435,7 @@
 				ast_msg_var_iterator_destroy(iter);
 				sip_pvt_unlock(pvt);
 				dialog_unlink_all(pvt);
-				dialog_unref(pvt, "MESSAGE(Max-Forwards) reached zero.");
+				ao2_s_cleanup(&pvt);
 				ast_log(LOG_NOTICE,
 					"MESSAGE(Max-Forwards) reached zero.  MESSAGE not sent.\n");
 				return -1;
@@ -27447,7 +27456,7 @@
 
 	sip_pvt_unlock(pvt);
 	sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT);
-	dialog_unref(pvt, "sent a MESSAGE");
+	ao2_s_cleanup(&pvt);
 
 	return res;
 }
@@ -28895,7 +28904,7 @@
 	ast_mutex_lock(&netlock);
 
 	/* Find the active SIP dialog or create a new one */
-	p = find_call(req, addr, req->method);	/* returns p with a reference only. _NOT_ locked*/
+	p = find_call(req, addr, req->method, &p);	/* returns p with a reference only. _NOT_ locked*/
 	if (p == NULL) {
 		ast_debug(1, "Invalid SIP message - rejected , no callid, len %zu\n", ast_str_strlen(req->data));
 		ast_mutex_unlock(&netlock);
@@ -28943,7 +28952,7 @@
 	if (p->logger_callid) {
 		ast_callid_threadassoc_remove();
 	}
-	ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
+	ao2_s_cleanup(&p);
 
 	return 1;
 }
@@ -29229,12 +29238,13 @@
 
 	if (peer->mwipvt) {
 		/* Base message on subscription */
-		p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt");
+		ao2_s_set(&p, peer->mwipvt);
 		ao2_unlock(peer);
 	} else {
 		ao2_unlock(peer);
 		/* Build temporary dialog for this message */
-		if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
+		sip_s_alloc(&p, NULL, NULL, 0, SIP_NOTIFY, NULL, 0);
+		if (!p) {
 			update_peer_lastmsgssent(peer, -1, 0);
 			return -1;
 		}
@@ -29247,7 +29257,7 @@
 		if (create_addr_from_peer(p, peer)) {
 			/* Maybe they're not registered, etc. */
 			dialog_unlink_all(p);
-			dialog_unref(p, "unref dialog p just created via sip_alloc");
+			ao2_s_cleanup(&p);
 			update_peer_lastmsgssent(peer, -1, 0);
 			return -1;
 		}
@@ -29279,7 +29289,7 @@
 	/* the following will decrement the refcount on p as it finishes */
 	transmit_notify_with_mwi(p, newmsgs, oldmsgs, vmexten);
 	sip_pvt_unlock(p);
-	dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
+	ao2_s_cleanup(&p);
 
 	update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0);
 
@@ -30030,7 +30040,8 @@
 		peer->call = dialog_unref(peer->call, "unref dialog peer->call");
 		/* peer->call = sip_destroy(peer->call); */
 	}
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL, 0))) {
+	sip_s_alloc(&p, NULL, NULL, 0, SIP_OPTIONS, NULL, 0);
+	if (!p) {
 		return -1;
 	}
 	peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
@@ -30095,7 +30106,7 @@
 				sip_unref_peer(peer, "removing poke peer ref"),
 				sip_ref_peer(peer, "adding poke peer ref"));
 	}
-	dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
+	ao2_s_cleanup(&p);
 	return 0;
 }
 
@@ -30261,7 +30272,8 @@
 	}
 
 	callid = ast_read_threadstorage_callid();
-	if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL, callid))) {
+	sip_s_alloc(&p, NULL, NULL, 0, SIP_INVITE, NULL, callid);
+	if (!p) {
 		ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
 		*cause = AST_CAUSE_SWITCH_CONGESTION;
 		return NULL;
@@ -30274,7 +30286,7 @@
 
 	if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
 		dialog_unlink_all(p);
-		dialog_unref(p, "unref dialog p from mem fail");
+		ao2_s_cleanup(&p);
 		/* sip_destroy(p); */
 		ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
 		*cause = AST_CAUSE_SWITCH_CONGESTION;
@@ -30395,7 +30407,7 @@
 		*cause = AST_CAUSE_UNREGISTERED;
 		ast_debug(3, "Cant create SIP call - target device not registered\n");
 		dialog_unlink_all(p);
-		dialog_unref(p, "unref dialog p UNREGISTERED");
+		ao2_s_cleanup(&p);
 		/* sip_destroy(p); */
 		return NULL;
 	}
@@ -30465,7 +30477,7 @@
 	} else {
 		ast_channel_unlock(tmpc);
 	}
-	dialog_unref(p, "toss pvt ptr at end of sip_request_call");
+	ao2_s_cleanup(&p);
 	ast_update_use_count();
 	restart_monitor();
 	return tmpc;
@@ -33727,10 +33739,10 @@
 	struct ao2_iterator iter;
 	struct sip_subscription_mwi *mwi;
 
-	iter = ao2_iterator_init(subscription_mwi_list, 0);
-	while ((mwi = ao2_t_iterator_next(&iter, "sip_send_all_mwi_subscriptions iter"))) {
+	ao2_s_iterator_init(&iter, subscription_mwi_list, 0);
+	while (ao2_s_iterator_next(&mwi, &iter)) {
 		start_mwi_subscription(mwi, 1);
-		ao2_t_ref(mwi, -1, "sip_send_all_mwi_subscriptions iter");
+		ao2_s_cleanup(&mwi);
 	}
 	ao2_iterator_destroy(&iter);
 }
@@ -35357,21 +35369,21 @@
 	ast_ssl_teardown(sip_tls_desc.tls_cfg);
 
 	/* Kill all existing TCP/TLS threads */
-	i = ao2_iterator_init(threadt, 0);
-	while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
+	ao2_s_iterator_init(&i, threadt, 0);
+	while (ao2_s_iterator_next(&th, &i)) {
 		pthread_t thread = th->threadid;
 		th->stop = 1;
 		pthread_kill(thread, SIGURG);
-		ao2_t_ref(th, -1, "decrement ref from iterator");
+		ao2_s_ref(&th, -1, "decrement ref from iterator");
 	}
 	ao2_iterator_destroy(&i);
 
 	/* Hangup all dialogs if they have an owner */
-	i = ao2_iterator_init(dialogs, 0);
-	while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
+	ao2_s_iterator_init(&i, dialogs, 0);
+	while (ao2_s_iterator_next(&p, &i)) {
 		if (p->owner)
 			ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
-		ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
+		ao2_s_ref(&p, -1, "toss dialog ptr from iterator_next");
 	}
 	ao2_iterator_destroy(&i);
 
@@ -35396,19 +35408,19 @@
 		struct ao2_iterator iter;
 		struct sip_subscription_mwi *mwi;
 
-		iter = ao2_iterator_init(subscription_mwi_list, 0);
-		while ((mwi = ao2_t_iterator_next(&iter, "unload_module iter"))) {
+		ao2_s_iterator_init(&iter, subscription_mwi_list, 0);
+		while (ao2_s_iterator_next(&mwi, &iter)) {
 			shutdown_mwi_subscription(mwi);
-			ao2_t_ref(mwi, -1, "unload_module iter");
+			ao2_s_cleanup(&mwi);
 		}
 		ao2_iterator_destroy(&iter);
 	}
 
 	/* Destroy all the dialogs and free their memory */
-	i = ao2_iterator_init(dialogs, 0);
-	while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
+	ao2_s_iterator_init(&i, dialogs, 0);
+	while (ao2_s_iterator_next(&p, &i)) {
 		dialog_unlink_all(p);
-		ao2_t_ref(p, -1, "throw away iterator result");
+		ao2_s_cleanup(&p);
 	}
 	ao2_iterator_destroy(&i);
 
diff --git a/channels/iax2/format_compatibility.c b/channels/iax2/format_compatibility.c
index 72fabf1..0d2c160 100644
--- a/channels/iax2/format_compatibility.c
+++ b/channels/iax2/format_compatibility.c
@@ -48,11 +48,13 @@
 	int x;
 
 	for (x = 0; x < ast_format_cap_count(cap); x++) {
-		struct ast_format *format = ast_format_cap_get_format(cap, x);
+		struct ast_format *format;
+
+		ast_s_format_cap_get_format(&format, cap, x);
 
 		bitfield |= ast_format_compatibility_format2bitfield(format);
 
-		ao2_ref(format, -1);
+		ao2_s_cleanup(&format);
 	}
 
 	return bitfield;
diff --git a/channels/iax2/provision.c b/channels/iax2/provision.c
index fcad2fe..736945e 100644
--- a/channels/iax2/provision.c
+++ b/channels/iax2/provision.c
@@ -348,9 +348,10 @@
 				ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "codec")) {
 			struct ast_format *tmpfmt;
-			if ((tmpfmt = ast_format_cache_get(v->value))) {
+			ast_s_format_cache_get(&tmpfmt, v->value);
+			if (tmpfmt) {
 				cur->format = ast_format_compatibility_format2bitfield(tmpfmt);
-				ao2_ref(tmpfmt, -1);
+				ao2_s_cleanup(&tmpfmt);
 			} else
 				ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "tos")) {
diff --git a/channels/sip/include/dialog.h b/channels/sip/include/dialog.h
index 0694170..1577d02 100644
--- a/channels/sip/include/dialog.h
+++ b/channels/sip/include/dialog.h
@@ -34,10 +34,13 @@
 
 struct sip_pvt *__sip_alloc(ast_string_field callid, struct ast_sockaddr *sin,
 				 int useglobal_nat, const int intended_method, struct sip_request *req, ast_callid logger_callid,
-				 const char *file, int line, const char *func);
+				 const char *file, int line, const char *func, void *debugstorage);
 
 #define sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid) \
-	__sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+	__sip_alloc(callid, addr, useglobal_nat, intended_method, req, logger_callid, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+
+#define sip_s_alloc(storage, callid, addr, useglobal_nat, intended_method, req, logger_callid) \
+	ao2_s_getter((storage), __sip_alloc, (callid), (addr), (useglobal_nat), (intended_method), (req), (logger_callid))
 
 /*!
  * \brief Schedule final destruction of SIP dialog.
diff --git a/include/asterisk/codec.h b/include/asterisk/codec.h
index 3873324..bcf45d7 100644
--- a/include/asterisk/codec.h
+++ b/include/asterisk/codec.h
@@ -131,7 +131,12 @@
  * \note The returned codec is reference counted and ao2_ref or ao2_cleanup
  * must be used to release the reference.
  */
-struct ast_codec *ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate);
+#define ast_codec_get(name, type, sample_rate) \
+	__ast_codec_get((name), (type), (sample_rate), NULL)
+struct ast_codec *__ast_codec_get(const char *name, enum ast_media_type type,
+	unsigned int sample_rate, void *debugstorage);
+#define ast_s_codec_get(storage, name, type, sample_rate) \
+	__ao2_s_getter(storage, __ast_codec_get, (name), (type), (sample_rate))
 
 /*!
  * \brief Retrieve a codec given the unique identifier
@@ -146,7 +151,11 @@
  * \note The returned codec is reference counted and ao2_ref or ao2_cleanup
  * must be used to release the reference.
  */
-struct ast_codec *ast_codec_get_by_id(int id);
+#define ast_codec_get_by_id(id) \
+	__ast_codec_get_by_id((id), NULL)
+struct ast_codec *__ast_codec_get_by_id(int id, void *debugstorage);
+#define ast_s_codec_get_by_id(storage, id) \
+	__ao2_s_getter(storage, __ast_codec_get_by_id, (id))
 
 /*!
  * \brief Retrieve the current maximum identifier for codec iteration
diff --git a/include/asterisk/format.h b/include/asterisk/format.h
index a5ca038..c02d6a6 100644
--- a/include/asterisk/format.h
+++ b/include/asterisk/format.h
@@ -153,7 +153,11 @@
  * \note The format is returned with reference count incremented. It must be released using
  * ao2_ref or ao2_cleanup.
  */
-struct ast_format *ast_format_create(struct ast_codec *codec);
+#define ast_format_create(codec) \
+	__ast_format_create((codec), NULL)
+struct ast_format *__ast_format_create(struct ast_codec *codec, void *debugstorage);
+#define ast_s_format_create(storage, codec) \
+	__ao2_s_getter(storage, __ast_format_create, (codec))
 
 /*!
  * \brief Create a new media format with a specific name
@@ -171,7 +175,12 @@
  * \retval non-NULL success
  * \retval NULL failure
  */
-struct ast_format *ast_format_create_named(const char *format_name, struct ast_codec *codec);
+#define ast_format_create_named(format_name, codec) \
+	__ast_format_create_named((format_name), (codec), NULL)
+struct ast_format *__ast_format_create_named(const char *format_name,
+	struct ast_codec *codec, void *debugstorage);
+#define ast_s_format_create_named(storage, format_name, codec) \
+	__ao2_s_getter(storage, __ast_format_create_named, (format_name), (codec))
 
 /*!
  * \brief Clone an existing media format so it can be modified
@@ -183,7 +192,11 @@
  * \retval non-NULL success
  * \retval NULL failure
  */
-struct ast_format *ast_format_clone(const struct ast_format *format);
+#define ast_format_clone(format) \
+	__ast_format_clone((format), NULL)
+struct ast_format *__ast_format_clone(const struct ast_format *format, void *debugstorage);
+#define ast_s_format_clone(storage, format) \
+	__ao2_s_getter(storage, __ast_format_clone, (format))
 
 /*!
  * \brief Compare two formats
@@ -307,7 +320,11 @@
  *
  * \note The reference count of the returned codec is increased by 1 and must be decremented
  */
-struct ast_codec *ast_format_get_codec(const struct ast_format *format);
+#define ast_format_get_codec(format) \
+	__ast_format_get_codec((format), NULL)
+struct ast_codec *__ast_format_get_codec(const struct ast_format *format, void *debugstorage);
+#define ast_s_format_get_codec(storage, format) \
+	__ao2_s_getter(storage, __ast_format_get_codec, (format))
 
 /*!
  * \brief Get the codec identifier associated with a format
diff --git a/include/asterisk/format_cache.h b/include/asterisk/format_cache.h
index 64e53b9..65b3e4a 100644
--- a/include/asterisk/format_cache.h
+++ b/include/asterisk/format_cache.h
@@ -253,13 +253,14 @@
  * dropped using ao2_ref or ao2_cleanup.
  */
 struct ast_format *__ast_format_cache_get(const char *name,
-	const char *tag, const char *file, int line, const char *func);
+	const char *tag, const char *file, int line, const char *func, void *debugstorage);
 
-#define ast_format_cache_get(name) \
-	__ast_format_cache_get((name), "ast_format_cache_get", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ast_t_format_cache_get(name, tag) \
-	__ast_format_cache_get((name), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
+	__ast_format_cache_get((name), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+#define ast_format_cache_get(name) \
+	__ast_format_cache_get((name), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+#define ast_s_format_cache_get(storage, name) \
+	ao2_s_getter(storage, __ast_format_cache_get, name, NULL)
 
 /*!
  * \brief Retrieve the best signed linear format given a sample rate.
diff --git a/include/asterisk/format_cap.h b/include/asterisk/format_cap.h
index 8b69e08..5b4b738 100644
--- a/include/asterisk/format_cap.h
+++ b/include/asterisk/format_cap.h
@@ -46,14 +46,15 @@
  * \retval ast_format_cap object on success.
  * \retval NULL on failure.
  */
-struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags,
-	const char *tag, const char *file, int line, const char *func);
-
 #define ast_format_cap_alloc(flags) \
-	__ast_format_cap_alloc((flags), "ast_format_cap_alloc", \
-		__FILE__, __LINE__, __PRETTY_FUNCTION__)
+	__ast_format_cap_alloc((flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags,
+	const char *tag, const char *file, int line, const char *func, void *debugstorage);
+
 #define ast_t_format_cap_alloc(flags, tag) \
-	__ast_format_cap_alloc((flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+	__ast_format_cap_alloc((flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+#define ast_s_format_cap_alloc(storage, flags) \
+	ao2_s_getter(storage, __ast_format_cap_alloc, (flags), NULL)
 
 /*!
  * \brief Set the global framing.
@@ -101,7 +102,7 @@
 	const char *tag, const char *file, int line, const char *func);
 
 #define ast_format_cap_append(cap, format, framing) \
-	__ast_format_cap_append((cap), (format), (framing), "ast_format_cap_append", \
+	__ast_format_cap_append((cap), (format), (framing), NULL, \
 		__FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ast_t_format_cap_append(cap, format, framing, tag) \
 	__ast_format_cap_append((cap), (format), (framing), (tag), \
@@ -187,7 +188,12 @@
  * \note The reference count of the returned format is increased. It must be released using ao2_ref
  * or ao2_cleanup.
  */
-struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position);
+#define ast_format_cap_get_format(cap, position) \
+	__ast_format_cap_get_format((cap), (position), NULL)
+struct ast_format *__ast_format_cap_get_format(const struct ast_format_cap *cap,
+	int position, void *debugstorage);
+#define ast_s_format_cap_get_format(storage, cap, position) \
+	__ao2_s_getter(storage, __ast_format_cap_get_format, (cap), (position))
 
 /*!
  * \brief Get the most preferred format for a particular media type
@@ -201,7 +207,12 @@
  * \note The reference count of the returned format is increased. It must be released using ao2_ref
  * or ao2_cleanup.
  */
-struct ast_format *ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type);
+#define ast_format_cap_get_best_by_type(cap, type) \
+	__ast_format_cap_get_best_by_type((cap), (type), NULL)
+struct ast_format *__ast_format_cap_get_best_by_type(const struct ast_format_cap *cap,
+	enum ast_media_type type, void *debugstorage);
+#define ast_s_format_cap_get_best_by_type(storage, cap, type) \
+	__ao2_s_getter(storage, __ast_format_cap_get_best_by_type, (cap), (type))
 
 /*!
  * \brief Get the framing for a format
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 351161c..77f4cce 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -829,7 +829,7 @@
 }
 void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
 {
-	ao2_replace(chan->nativeformats, value);
+	ao2_s_replace(&chan->nativeformats, value);
 }
 struct ast_framehook_list *ast_channel_framehooks(const struct ast_channel *chan)
 {
@@ -948,23 +948,23 @@
 }
 void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
 {
-	ao2_replace(chan->oldwriteformat, format);
+	ao2_s_replace(&chan->oldwriteformat, format);
 }
 void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
 {
-	ao2_replace(chan->rawreadformat, format);
+	ao2_s_replace(&chan->rawreadformat, format);
 }
 void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
 {
-	ao2_replace(chan->rawwriteformat, format);
+	ao2_s_replace(&chan->rawwriteformat, format);
 }
 void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
 {
-	ao2_replace(chan->readformat, format);
+	ao2_s_replace(&chan->readformat, format);
 }
 void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
 {
-	ao2_replace(chan->writeformat, format);
+	ao2_s_replace(&chan->writeformat, format);
 }
 struct ast_format *ast_channel_oldwriteformat(struct ast_channel *chan)
 {
diff --git a/main/codec.c b/main/codec.c
index 49356a2..b45a634 100644
--- a/main/codec.c
+++ b/main/codec.c
@@ -309,16 +309,16 @@
 		}
 	}
 
-	codec_new = ao2_find(codecs, codec, OBJ_SEARCH_OBJECT | OBJ_NOLOCK);
+	codec_new = ao2_find_full(codecs, codec, OBJ_SEARCH_OBJECT | OBJ_NOLOCK, "", &codec_new);
 	if (codec_new) {
 		ast_log(LOG_ERROR, "A codec with name '%s' of type '%s' and sample rate '%u' is already registered\n",
 			codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
-		ao2_ref(codec_new, -1);
+		ao2_s_cleanup(&codec_new);
 		return -1;
 	}
 
-	codec_new = ao2_t_alloc_options(sizeof(*codec_new), codec_dtor,
-		AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""));
+	codec_new = ao2_alloc_full(sizeof(*codec_new), codec_dtor,
+		AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""), &codec_new);
 	if (!codec_new) {
 		ast_log(LOG_ERROR, "Could not allocate a codec with name '%s' of type '%s' and sample rate '%u'\n",
 			codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
@@ -336,12 +336,13 @@
 	ast_verb(2, "Registered '%s' codec '%s' at sample rate '%u' with id '%u'\n",
 		ast_codec_media_type2str(codec->type), codec->name, codec->sample_rate, codec_new->external.id);
 
-	ao2_ref(codec_new, -1);
+	ao2_s_cleanup(&codec_new);
 
 	return 0;
 }
 
-struct ast_codec *ast_codec_get(const char *name, enum ast_media_type type, unsigned int sample_rate)
+struct ast_codec *__ast_codec_get(const char *name, enum ast_media_type type,
+	unsigned int sample_rate, void *debugstorage)
 {
 	struct ast_codec codec = {
 		.name = name,
@@ -349,12 +350,12 @@
 		.sample_rate = sample_rate,
 	};
 
-	return ao2_find(codecs, &codec, OBJ_SEARCH_OBJECT);
+	return ao2_find_full(codecs, &codec, OBJ_SEARCH_OBJECT, NULL, debugstorage);
 }
 
-struct ast_codec *ast_codec_get_by_id(int id)
+struct ast_codec *__ast_codec_get_by_id(int id, void *debugstorage)
 {
-	return ao2_callback(codecs, 0, codec_id_cmp, &id);
+	return ao2_callback_full(codecs, 0, codec_id_cmp, &id, NULL, debugstorage);
 }
 
 int ast_codec_get_max(void)
diff --git a/main/codec_builtin.c b/main/codec_builtin.c
index 9131643..a7a6280 100644
--- a/main/codec_builtin.c
+++ b/main/codec_builtin.c
@@ -775,28 +775,30 @@
 #define CODEC_REGISTER_AND_CACHE(codec) \
 	({ \
 		int __res_ ## __LINE__ = 0; \
-		struct ast_format *__fmt_ ## __LINE__; \
+		struct ast_format *__fmt_ ## __LINE__ = NULL; \
 		struct ast_codec *__codec_ ## __LINE__; \
 		res |= __ast_codec_register_with_format(&(codec), (codec).name, NULL); \
-		__codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
-		__fmt_ ## __LINE__ = __codec_ ## __LINE__ ? ast_format_create(__codec_ ## __LINE__) : NULL; \
+		ast_s_codec_get(&__codec_ ## __LINE__, (codec).name, (codec).type, (codec).sample_rate); \
+		if (__codec_ ## __LINE__) { \
+			ast_s_format_create(&__fmt_ ## __LINE__, __codec_ ## __LINE__); \
+		} \
 		res |= ast_format_cache_set(__fmt_ ## __LINE__); \
-		ao2_ref(__fmt_ ## __LINE__, -1); \
-		ao2_ref(__codec_ ## __LINE__, -1); \
+		ao2_s_cleanup(&__fmt_ ## __LINE__); \
+		ao2_s_cleanup(&__codec_ ## __LINE__); \
 		__res_ ## __LINE__; \
 	})
 
 #define CODEC_REGISTER_AND_CACHE_NAMED(fmt_name, codec) \
 	({ \
 		int __res_ ## __LINE__ = 0; \
-		struct ast_format *__fmt_ ## __LINE__; \
+		struct ast_format *__fmt_ ## __LINE__ = NULL; \
 		struct ast_codec *__codec_ ## __LINE__; \
 		res |= __ast_codec_register_with_format(&(codec), fmt_name, NULL); \
-		__codec_ ## __LINE__ = ast_codec_get((codec).name, (codec).type, (codec).sample_rate); \
-		__fmt_ ## __LINE__ = ast_format_create_named((fmt_name), __codec_ ## __LINE__); \
+		ast_s_codec_get(&__codec_ ## __LINE__, (codec).name, (codec).type, (codec).sample_rate); \
+		ast_s_format_create_named(&__fmt_ ## __LINE__, (fmt_name), __codec_ ## __LINE__); \
 		res |= ast_format_cache_set(__fmt_ ## __LINE__); \
-		ao2_ref(__fmt_ ## __LINE__, -1); \
-		ao2_ref(__codec_ ## __LINE__, -1); \
+		ao2_s_cleanup(&__fmt_ ## __LINE__); \
+		ao2_s_cleanup(&__codec_ ## __LINE__); \
 		__res_ ## __LINE__; \
 	})
 
diff --git a/main/format.c b/main/format.c
index cc9ac45..4a943b1 100644
--- a/main/format.c
+++ b/main/format.c
@@ -186,21 +186,22 @@
 		format->interface->format_destroy(format);
 	}
 
-	ao2_cleanup(format->codec);
+	ao2_s_cleanup(&format->codec);
 }
 
-struct ast_format *ast_format_create_named(const char *format_name, struct ast_codec *codec)
+struct ast_format *__ast_format_create_named(const char *format_name,
+	struct ast_codec *codec, void *debugstorage)
 {
 	struct ast_format *format;
 	struct format_interface *format_interface;
 
-	format = ao2_t_alloc_options(sizeof(*format), format_destroy,
-		AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""));
+	format = ao2_alloc_full(sizeof(*format), format_destroy,
+		AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""), debugstorage);
 	if (!format) {
 		return NULL;
 	}
 	format->name = format_name;
-	format->codec = ao2_bump(codec);
+	ao2_s_set(&format->codec, codec);
 
 	format_interface = ao2_find(interfaces, codec->name, OBJ_SEARCH_KEY);
 	if (format_interface) {
@@ -211,25 +212,25 @@
 	return format;
 }
 
-struct ast_format *ast_format_clone(const struct ast_format *format)
+struct ast_format *__ast_format_clone(const struct ast_format *format, void *debugstorage)
 {
-	struct ast_format *cloned = ast_format_create_named(format->name, format->codec);
+	struct ast_format *cloned = __ast_format_create_named(format->name, format->codec, debugstorage);
 
 	if (!cloned) {
 		return NULL;
 	}
 
 	if (cloned->interface && cloned->interface->format_clone(format, cloned)) {
-		ao2_ref(cloned, -1);
+		ao2_ref_full(cloned, -1, "", debugstorage);
 		return NULL;
 	}
 
 	return cloned;
 }
 
-struct ast_format *ast_format_create(struct ast_codec *codec)
+struct ast_format *__ast_format_create(struct ast_codec *codec, void *debugstorage)
 {
-	return ast_format_create_named(codec->name, codec);
+	return __ast_format_create_named(codec->name, codec, debugstorage);
 }
 
 enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
@@ -355,9 +356,9 @@
 	interface->format_generate_sdp_fmtp(format, payload, str);
 }
 
-struct ast_codec *ast_format_get_codec(const struct ast_format *format)
+struct ast_codec *__ast_format_get_codec(const struct ast_format *format, void *debugstorage)
 {
-	return ao2_bump(format->codec);
+	return ao2_bump_full(format->codec, "", debugstorage);
 }
 
 unsigned int ast_format_get_codec_id(const struct ast_format *format)
diff --git a/main/format_cache.c b/main/format_cache.c
index def795c..addaff1 100644
--- a/main/format_cache.c
+++ b/main/format_cache.c
@@ -292,45 +292,45 @@
 	ao2_cleanup(formats);
 	formats = NULL;
 
-	ao2_replace(ast_format_g723, NULL);
-	ao2_replace(ast_format_ulaw, NULL);
-	ao2_replace(ast_format_alaw, NULL);
-	ao2_replace(ast_format_gsm, NULL);
-	ao2_replace(ast_format_g726, NULL);
-	ao2_replace(ast_format_g726_aal2, NULL);
-	ao2_replace(ast_format_adpcm, NULL);
-	ao2_replace(ast_format_slin, NULL);
-	ao2_replace(ast_format_slin12, NULL);
-	ao2_replace(ast_format_slin16, NULL);
-	ao2_replace(ast_format_slin24, NULL);
-	ao2_replace(ast_format_slin32, NULL);
-	ao2_replace(ast_format_slin44, NULL);
-	ao2_replace(ast_format_slin48, NULL);
-	ao2_replace(ast_format_slin96, NULL);
-	ao2_replace(ast_format_slin192, NULL);
-	ao2_replace(ast_format_lpc10, NULL);
-	ao2_replace(ast_format_g729, NULL);
-	ao2_replace(ast_format_speex, NULL);
-	ao2_replace(ast_format_speex16, NULL);
-	ao2_replace(ast_format_speex32, NULL);
-	ao2_replace(ast_format_ilbc, NULL);
-	ao2_replace(ast_format_g722, NULL);
-	ao2_replace(ast_format_siren7, NULL);
-	ao2_replace(ast_format_siren14, NULL);
-	ao2_replace(ast_format_testlaw, NULL);
-	ao2_replace(ast_format_g719, NULL);
-	ao2_replace(ast_format_opus, NULL);
-	ao2_replace(ast_format_jpeg, NULL);
-	ao2_replace(ast_format_png, NULL);
-	ao2_replace(ast_format_h261, NULL);
-	ao2_replace(ast_format_h263, NULL);
-	ao2_replace(ast_format_h263p, NULL);
-	ao2_replace(ast_format_h264, NULL);
-	ao2_replace(ast_format_mp4, NULL);
-	ao2_replace(ast_format_vp8, NULL);
-	ao2_replace(ast_format_t140_red, NULL);
-	ao2_replace(ast_format_t140, NULL);
-	ao2_replace(ast_format_none, NULL);
+	ao2_s_replace(&ast_format_g723, NULL);
+	ao2_s_replace(&ast_format_ulaw, NULL);
+	ao2_s_replace(&ast_format_alaw, NULL);
+	ao2_s_replace(&ast_format_gsm, NULL);
+	ao2_s_replace(&ast_format_g726, NULL);
+	ao2_s_replace(&ast_format_g726_aal2, NULL);
+	ao2_s_replace(&ast_format_adpcm, NULL);
+	ao2_s_replace(&ast_format_slin, NULL);
+	ao2_s_replace(&ast_format_slin12, NULL);
+	ao2_s_replace(&ast_format_slin16, NULL);
+	ao2_s_replace(&ast_format_slin24, NULL);
+	ao2_s_replace(&ast_format_slin32, NULL);
+	ao2_s_replace(&ast_format_slin44, NULL);
+	ao2_s_replace(&ast_format_slin48, NULL);
+	ao2_s_replace(&ast_format_slin96, NULL);
+	ao2_s_replace(&ast_format_slin192, NULL);
+	ao2_s_replace(&ast_format_lpc10, NULL);
+	ao2_s_replace(&ast_format_g729, NULL);
+	ao2_s_replace(&ast_format_speex, NULL);
+	ao2_s_replace(&ast_format_speex16, NULL);
+	ao2_s_replace(&ast_format_speex32, NULL);
+	ao2_s_replace(&ast_format_ilbc, NULL);
+	ao2_s_replace(&ast_format_g722, NULL);
+	ao2_s_replace(&ast_format_siren7, NULL);
+	ao2_s_replace(&ast_format_siren14, NULL);
+	ao2_s_replace(&ast_format_testlaw, NULL);
+	ao2_s_replace(&ast_format_g719, NULL);
+	ao2_s_replace(&ast_format_opus, NULL);
+	ao2_s_replace(&ast_format_jpeg, NULL);
+	ao2_s_replace(&ast_format_png, NULL);
+	ao2_s_replace(&ast_format_h261, NULL);
+	ao2_s_replace(&ast_format_h263, NULL);
+	ao2_s_replace(&ast_format_h263p, NULL);
+	ao2_s_replace(&ast_format_h264, NULL);
+	ao2_s_replace(&ast_format_mp4, NULL);
+	ao2_s_replace(&ast_format_vp8, NULL);
+	ao2_s_replace(&ast_format_t140_red, NULL);
+	ao2_s_replace(&ast_format_t140, NULL);
+	ao2_s_replace(&ast_format_none, NULL);
 }
 
 int ast_format_cache_init(void)
@@ -349,83 +349,83 @@
 static void set_cached_format(const char *name, struct ast_format *format)
 {
 	if (!strcmp(name, "g723")) {
-		ao2_replace(ast_format_g723, format);
+		ao2_s_replace(&ast_format_g723, format);
 	} else if (!strcmp(name, "ulaw")) {
-		ao2_replace(ast_format_ulaw, format);
+		ao2_s_replace(&ast_format_ulaw, format);
 	} else if (!strcmp(name, "alaw")) {
-		ao2_replace(ast_format_alaw, format);
+		ao2_s_replace(&ast_format_alaw, format);
 	} else if (!strcmp(name, "gsm")) {
-		ao2_replace(ast_format_gsm, format);
+		ao2_s_replace(&ast_format_gsm, format);
 	} else if (!strcmp(name, "g726")) {
-		ao2_replace(ast_format_g726, format);
+		ao2_s_replace(&ast_format_g726, format);
 	} else if (!strcmp(name, "g726aal2")) {
-		ao2_replace(ast_format_g726_aal2, format);
+		ao2_s_replace(&ast_format_g726_aal2, format);
 	} else if (!strcmp(name, "adpcm")) {
-		ao2_replace(ast_format_adpcm, format);
+		ao2_s_replace(&ast_format_adpcm, format);
 	} else if (!strcmp(name, "slin")) {
-		ao2_replace(ast_format_slin, format);
+		ao2_s_replace(&ast_format_slin, format);
 	} else if (!strcmp(name, "slin12")) {
-		ao2_replace(ast_format_slin12, format);
+		ao2_s_replace(&ast_format_slin12, format);
 	} else if (!strcmp(name, "slin16")) {
-		ao2_replace(ast_format_slin16, format);
+		ao2_s_replace(&ast_format_slin16, format);
 	} else if (!strcmp(name, "slin24")) {
-		ao2_replace(ast_format_slin24, format);
+		ao2_s_replace(&ast_format_slin24, format);
 	} else if (!strcmp(name, "slin32")) {
-		ao2_replace(ast_format_slin32, format);
+		ao2_s_replace(&ast_format_slin32, format);
 	} else if (!strcmp(name, "slin44")) {
-		ao2_replace(ast_format_slin44, format);
+		ao2_s_replace(&ast_format_slin44, format);
 	} else if (!strcmp(name, "slin48")) {
-		ao2_replace(ast_format_slin48, format);
+		ao2_s_replace(&ast_format_slin48, format);
 	} else if (!strcmp(name, "slin96")) {
-		ao2_replace(ast_format_slin96, format);
+		ao2_s_replace(&ast_format_slin96, format);
 	} else if (!strcmp(name, "slin192")) {
-		ao2_replace(ast_format_slin192, format);
+		ao2_s_replace(&ast_format_slin192, format);
 	} else if (!strcmp(name, "lpc10")) {
-		ao2_replace(ast_format_lpc10, format);
+		ao2_s_replace(&ast_format_lpc10, format);
 	} else if (!strcmp(name, "g729")) {
-		ao2_replace(ast_format_g729, format);
+		ao2_s_replace(&ast_format_g729, format);
 	} else if (!strcmp(name, "speex")) {
-		ao2_replace(ast_format_speex, format);
+		ao2_s_replace(&ast_format_speex, format);
 	} else if (!strcmp(name, "speex16")) {
-		ao2_replace(ast_format_speex16, format);
+		ao2_s_replace(&ast_format_speex16, format);
 	} else if (!strcmp(name, "speex32")) {
-		ao2_replace(ast_format_speex32, format);
+		ao2_s_replace(&ast_format_speex32, format);
 	} else if (!strcmp(name, "ilbc")) {
-		ao2_replace(ast_format_ilbc, format);
+		ao2_s_replace(&ast_format_ilbc, format);
 	} else if (!strcmp(name, "g722")) {
-		ao2_replace(ast_format_g722, format);
+		ao2_s_replace(&ast_format_g722, format);
 	} else if (!strcmp(name, "siren7")) {
-		ao2_replace(ast_format_siren7, format);
+		ao2_s_replace(&ast_format_siren7, format);
 	} else if (!strcmp(name, "siren14")) {
-		ao2_replace(ast_format_siren14, format);
+		ao2_s_replace(&ast_format_siren14, format);
 	} else if (!strcmp(name, "testlaw")) {
-		ao2_replace(ast_format_testlaw, format);
+		ao2_s_replace(&ast_format_testlaw, format);
 	} else if (!strcmp(name, "g719")) {
-		ao2_replace(ast_format_g719, format);
+		ao2_s_replace(&ast_format_g719, format);
 	} else if (!strcmp(name, "opus")) {
-		ao2_replace(ast_format_opus, format);
+		ao2_s_replace(&ast_format_opus, format);
 	} else if (!strcmp(name, "jpeg")) {
-		ao2_replace(ast_format_jpeg, format);
+		ao2_s_replace(&ast_format_jpeg, format);
 	} else if (!strcmp(name, "png")) {
-		ao2_replace(ast_format_png, format);
+		ao2_s_replace(&ast_format_png, format);
 	} else if (!strcmp(name, "h261")) {
-		ao2_replace(ast_format_h261, format);
+		ao2_s_replace(&ast_format_h261, format);
 	} else if (!strcmp(name, "h263")) {
-		ao2_replace(ast_format_h263, format);
+		ao2_s_replace(&ast_format_h263, format);
 	} else if (!strcmp(name, "h263p")) {
-		ao2_replace(ast_format_h263p, format);
+		ao2_s_replace(&ast_format_h263p, format);
 	} else if (!strcmp(name, "h264")) {
-		ao2_replace(ast_format_h264, format);
+		ao2_s_replace(&ast_format_h264, format);
 	} else if (!strcmp(name, "mpeg4")) {
-		ao2_replace(ast_format_mp4, format);
+		ao2_s_replace(&ast_format_mp4, format);
 	} else if (!strcmp(name, "vp8")) {
-		ao2_replace(ast_format_vp8, format);
+		ao2_s_replace(&ast_format_vp8, format);
 	} else if (!strcmp(name, "red")) {
-		ao2_replace(ast_format_t140_red, format);
+		ao2_s_replace(&ast_format_t140_red, format);
 	} else if (!strcmp(name, "t140")) {
-		ao2_replace(ast_format_t140, format);
+		ao2_s_replace(&ast_format_t140, format);
 	} else if (!strcmp(name, "none")) {
-		ao2_replace(ast_format_none, format);
+		ao2_s_replace(&ast_format_none, format);
 	}
 }
 
@@ -458,13 +458,14 @@
 }
 
 struct ast_format *__ast_format_cache_get(const char *name,
-	const char *tag, const char *file, int line, const char *func)
+	const char *tag, const char *file, int line, const char *func, void *debugstorage)
 {
 	if (ast_strlen_zero(name)) {
 		return NULL;
 	}
 
-	return __ao2_find(formats, name, OBJ_SEARCH_KEY, tag, file, line, func);
+	return __ao2_find_full(formats, name, OBJ_SEARCH_KEY,
+		tag ?: __PRETTY_FUNCTION__, file, line, func, debugstorage);
 }
 
 struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate)
diff --git a/main/format_cap.c b/main/format_cap.c
index 6a9d4f8..8adb4be 100644
--- a/main/format_cap.c
+++ b/main/format_cap.c
@@ -79,7 +79,7 @@
 		struct format_cap_framed *framed;
 
 		while ((framed = AST_LIST_REMOVE_HEAD(list, entry))) {
-			ao2_ref(framed, -1);
+			ao2_ref_full(framed, -1, "", &cap->formats);
 		}
 	}
 	AST_VECTOR_FREE(&cap->formats);
@@ -88,7 +88,7 @@
 		struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, idx);
 
 		/* This will always be non-null, unlike formats */
-		ao2_ref(framed, -1);
+		ao2_ref_full(framed, -1, "", &cap->preference_order);
 	}
 	AST_VECTOR_FREE(&cap->preference_order);
 }
@@ -117,18 +117,18 @@
 }
 
 struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags,
-	const char *tag, const char *file, int line, const char *func)
+	const char *tag, const char *file, int line, const char *func, void *debugstorage)
 {
 	struct ast_format_cap *cap;
 
 	cap = __ao2_alloc_full(sizeof(*cap), format_cap_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK,
-		tag, file, line, func, NULL);
+		tag ?: "ast_format_cap_alloc", file, line, func, debugstorage);
 	if (!cap) {
 		return NULL;
 	}
 
 	if (format_cap_init(cap, flags)) {
-		ao2_ref(cap, -1);
+		ao2_ref_full(cap, -1, "format_cap_init: Failed", debugstorage);
 		return NULL;
 	}
 
@@ -145,7 +145,7 @@
 {
 	struct format_cap_framed *framed = obj;
 
-	ao2_cleanup(framed->format);
+	ao2_s_cleanup(&framed->format);
 }
 
 static inline int format_cap_framed_init(struct format_cap_framed *framed, struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
@@ -156,17 +156,17 @@
 
 	if (ast_format_get_codec_id(format) >= AST_VECTOR_SIZE(&cap->formats)) {
 		if (AST_VECTOR_REPLACE(&cap->formats, ast_format_get_codec_id(format), format_cap_framed_list_empty)) {
-			ao2_ref(framed, -1);
+			ao2_ref_full(framed, -1, "", &cap->formats);
 			return -1;
 		}
 	}
 	list = AST_VECTOR_GET_ADDR(&cap->formats, ast_format_get_codec_id(format));
 
 	/* Order doesn't matter for formats, so insert at the head for performance reasons */
-	ao2_ref(framed, +1);
+	/* This takes the allocation reference */
 	AST_LIST_INSERT_HEAD(list, framed, entry);
 
-	/* This takes the allocation reference */
+	ao2_ref_full(framed, +1, "", &cap->preference_order);
 	AST_VECTOR_APPEND(&cap->preference_order, framed);
 
 	cap->framing = MIN(cap->framing, framing ? framing : ast_format_get_default_ms(format));
@@ -201,12 +201,13 @@
 		return 0;
 	}
 
-	framed = ao2_alloc_options(sizeof(*framed), format_cap_framed_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	framed = ao2_alloc_full(sizeof(*framed), format_cap_framed_destroy,
+		AO2_ALLOC_OPT_LOCK_NOLOCK, "", &cap->formats);
 	if (!framed) {
 		return -1;
 	}
 
-	__ao2_ref(format, +1, tag, file, line, func);
+	__ao2_ref_full(format, +1, tag ?: "ast_format_cap_append", file, line, func, &framed->format);
 	framed->format = format;
 
 	return format_cap_framed_init(framed, cap, format, framing);
@@ -217,37 +218,38 @@
 	int id;
 
 	for (id = 1; id < ast_codec_get_max(); ++id) {
-		struct ast_codec *codec = ast_codec_get_by_id(id);
+		struct ast_codec *codec;
 		struct ast_codec *codec2 = NULL;
 		struct ast_format *format;
 		int res;
 
+		ast_s_codec_get_by_id(&codec, id);
 		if (!codec) {
 			continue;
 		}
 
 		if ((type != AST_MEDIA_TYPE_UNKNOWN) && codec->type != type) {
-			ao2_ref(codec, -1);
+			ao2_s_cleanup(&codec);
 			continue;
 		}
 
-		format = ast_format_cache_get(codec->name);
+		ast_s_format_cache_get(&format, codec->name);
 
 		if (format == ast_format_none) {
-			ao2_ref(format, -1);
-			ao2_ref(codec, -1);
+			ao2_s_cleanup(&format);
+			ao2_s_cleanup(&codec);
 			continue;
 		}
 
 		if (format) {
-			codec2 = ast_format_get_codec(format);
+			ast_s_format_get_codec(&codec2, format);
 		}
 		if (codec != codec2) {
-			ao2_cleanup(format);
-			format = ast_format_create(codec);
+			ao2_s_cleanup(&format);
+			ast_s_format_create(&format, codec);
 		}
-		ao2_cleanup(codec2);
-		ao2_ref(codec, -1);
+		ao2_s_cleanup(&codec2);
+		ao2_s_cleanup(&codec);
 
 		if (!format) {
 			return -1;
@@ -255,7 +257,7 @@
 
 		/* Use the global framing or default framing of the codec */
 		res = ast_format_cap_append(cap, format, 0);
-		ao2_ref(format, -1);
+		ao2_s_cleanup(&format);
 
 		if (res) {
 			return -1;
@@ -292,8 +294,7 @@
 		framed = AST_VECTOR_GET(&cap->preference_order, i);
 
 		if (ast_format_get_codec_id(format) == ast_format_get_codec_id(framed->format)) {
-			ao2_t_replace(framed->format, format, "replacing with new format");
-			framed->framing = framing;
+			ao2_s_replace(&framed->format, format);
 			return 0;
 		}
 	}
@@ -395,7 +396,8 @@
 	return AST_VECTOR_SIZE(&cap->preference_order);
 }
 
-struct ast_format *ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
+struct ast_format *__ast_format_cap_get_format(const struct ast_format_cap *cap,
+	int position, void *debugstorage)
 {
 	struct format_cap_framed *framed;
 
@@ -408,23 +410,24 @@
 	framed = AST_VECTOR_GET(&cap->preference_order, position);
 
 	ast_assert(framed->format != ast_format_none);
-	ao2_ref(framed->format, +1);
+	ao2_ref_full(framed->format, +1, "", debugstorage);
 	return framed->format;
 }
 
-struct ast_format *ast_format_cap_get_best_by_type(const struct ast_format_cap *cap, enum ast_media_type type)
+struct ast_format *__ast_format_cap_get_best_by_type(const struct ast_format_cap *cap,
+	enum ast_media_type type, void *debugstorage)
 {
 	int i;
 
 	if (type == AST_MEDIA_TYPE_UNKNOWN) {
-		return ast_format_cap_get_format(cap, 0);
+		return __ast_format_cap_get_format(cap, 0, debugstorage);
 	}
 
 	for (i = 0; i < AST_VECTOR_SIZE(&cap->preference_order); i++) {
 		struct format_cap_framed *framed = AST_VECTOR_GET(&cap->preference_order, i);
 
 		if (ast_format_get_type(framed->format) == type) {
-			ao2_ref(framed->format, +1);
+			ao2_ref_full(framed->format, +1, "", debugstorage);
 			ast_assert(framed->format != ast_format_none);
 			return framed->format;
 		}
diff --git a/main/frame.c b/main/frame.c
index 92b92b6..1251ed9 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -130,7 +130,7 @@
 		    (frames->size < FRAME_CACHE_MAX_SIZE)) {
 			if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
 				(fr->frametype == AST_FRAME_IMAGE)) {
-				ao2_cleanup(fr->subclass.format);
+				ao2_s_cleanup(&fr->subclass.format);
 			}
 
 			AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list);
@@ -151,7 +151,7 @@
 	if (fr->mallocd & AST_MALLOCD_HDR) {
 		if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
 			(fr->frametype == AST_FRAME_IMAGE)) {
-			ao2_cleanup(fr->subclass.format);
+			ao2_s_cleanup(&fr->subclass.format);
 		}
 
 		ast_free(fr);
@@ -210,7 +210,7 @@
 		out->frametype = fr->frametype;
 		if ((fr->frametype == AST_FRAME_VOICE) || (fr->frametype == AST_FRAME_VIDEO) ||
 			(fr->frametype == AST_FRAME_IMAGE)) {
-			out->subclass.format = ao2_bump(fr->subclass.format);
+			ao2_s_set(&out->subclass.format, fr->subclass.format);
 		} else {
 			memcpy(&out->subclass, &fr->subclass, sizeof(out->subclass));
 		}
@@ -323,7 +323,7 @@
 	out->subclass = f->subclass;
 	if ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO) ||
 		(f->frametype == AST_FRAME_IMAGE)) {
-		ao2_bump(out->subclass.format);
+		ao2_s_init(&out->subclass.format);
 	}
 	out->datalen = f->datalen;
 	out->samples = f->samples;
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 11e94c6..244348c 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -2220,7 +2220,7 @@
  */
 static void rtp_engine_mime_type_cleanup(int i)
 {
-	ao2_cleanup(ast_rtp_mime_types[i].payload_type.format);
+	ao2_s_cleanup(&ast_rtp_mime_types[i].payload_type.format);
 	memset(&ast_rtp_mime_types[i], 0, sizeof(struct ast_rtp_mime_type));
 }
 
@@ -2240,7 +2240,7 @@
 	memset(&ast_rtp_mime_types[x], 0, sizeof(struct ast_rtp_mime_type));	
 	if (format) {
 		ast_rtp_mime_types[x].payload_type.asterisk_format = 1;
-		ast_rtp_mime_types[x].payload_type.format = ao2_bump(format);
+		ao2_s_set(&ast_rtp_mime_types[x].payload_type.format, format);
 	} else {
 		ast_rtp_mime_types[x].payload_type.rtp_code = rtp_code;
 	}
diff --git a/main/stasis.c b/main/stasis.c
index 91ad94e..85a1bbc 100644
--- a/main/stasis.c
+++ b/main/stasis.c
@@ -405,7 +405,7 @@
 	 * be bad. */
 	ast_assert(stasis_subscription_is_done(sub));
 
-	ao2_cleanup(sub->topic);
+	ao2_s_cleanup(&sub->topic);
 	sub->topic = NULL;
 	ast_taskprocessor_unreference(sub->mailbox);
 	sub->mailbox = NULL;
@@ -494,8 +494,7 @@
 		ao2_ref(sub, +1);
 	}
 
-	ao2_ref(topic, +1);
-	sub->topic = topic;
+	ao2_s_set(&sub->topic, topic);
 	sub->callback = callback;
 	sub->data = data;
 	ast_cond_init(&sub->join_cond, NULL);
@@ -536,8 +535,7 @@
 {
 	/* The subscription may be the last ref to this topic. Hold
 	 * the topic ref open until after the unlock. */
-	RAII_VAR(struct stasis_topic *, topic,
-		ao2_bump(sub ? sub->topic : NULL), ao2_cleanup);
+	RAII_AO2_S_BUMP(struct stasis_topic *, topic, sub ? sub->topic : NULL);
 
 	if (!sub) {
 		return NULL;
@@ -824,7 +822,7 @@
 	 * The topic may be unref'ed by the subscription invocation.
 	 * Make sure we hold onto a reference while dispatching.
 	 */
-	ao2_ref(topic, +1);
+	ao2_s_init(&topic);
 	ao2_lock(topic);
 	for (i = 0; i < AST_VECTOR_SIZE(&topic->subscribers); ++i) {
 		struct stasis_subscription *sub = AST_VECTOR_GET(&topic->subscribers, i);
@@ -834,7 +832,7 @@
 		dispatch_message(sub, message, (sub == sync_sub));
 	}
 	ao2_unlock(topic);
-	ao2_ref(topic, -1);
+	ao2_s_cleanup(&topic);
 }
 
 void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
@@ -868,10 +866,8 @@
 {
 	struct stasis_forward *forward = obj;
 
-	ao2_cleanup(forward->from_topic);
-	forward->from_topic = NULL;
-	ao2_cleanup(forward->to_topic);
-	forward->to_topic = NULL;
+	ao2_s_cleanup(&forward->from_topic);
+	ao2_s_cleanup(&forward->to_topic);
 }
 
 struct stasis_forward *stasis_forward_cancel(struct stasis_forward *forward)
@@ -925,8 +921,8 @@
 		return ao2_bump(forward);
 	}
 
-	forward->from_topic = ao2_bump(from_topic);
-	forward->to_topic = ao2_bump(to_topic);
+	ao2_s_set(&forward->from_topic, from_topic);
+	ao2_s_set(&forward->to_topic, to_topic);
 
 	topic_lock_both(to_topic, from_topic);
 	res = AST_VECTOR_APPEND(&to_topic->upstream_topics, from_topic);
@@ -950,7 +946,7 @@
 	struct stasis_subscription_change *change = obj;
 
 	ast_string_field_free_memory(change);
-	ao2_cleanup(change->topic);
+	ao2_s_cleanup(&change->topic);
 }
 
 static struct stasis_subscription_change *subscription_change_alloc(struct stasis_topic *topic, const char *uniqueid, const char *description)
@@ -965,8 +961,7 @@
 
 	ast_string_field_set(change, uniqueid, uniqueid);
 	ast_string_field_set(change, description, description);
-	ao2_ref(topic, +1);
-	change->topic = topic;
+	ao2_s_set(&change->topic, topic);
 
 	return change;
 }
@@ -1477,7 +1472,7 @@
 {
 	struct stasis_config *cfg = obj;
 
-	ao2_cleanup(cfg->declined_message_types);
+	ao2_s_cleanup(&cfg->declined_message_types);
 	ast_free(cfg->threadpool_options);
 }
 
@@ -1495,8 +1490,9 @@
 		return NULL;
 	}
 
-	cfg->declined_message_types = ao2_alloc(sizeof(*cfg->declined_message_types),
-		stasis_declined_config_destructor);
+	cfg->declined_message_types = ao2_alloc_full(sizeof(*cfg->declined_message_types),
+		stasis_declined_config_destructor, AO2_ALLOC_OPT_LOCK_MUTEX,
+		"", &cfg->declined_message_types);
 	if (!cfg->declined_message_types) {
 		ao2_ref(cfg, -1);
 		return NULL;
@@ -1513,7 +1509,7 @@
 
 int stasis_message_type_declined(const char *name)
 {
-	RAII_VAR(struct stasis_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
+	RAII_AO2_S_GLOBAL(struct stasis_config *, cfg, globals);
 	char *name_in_declined;
 	int res;
 
diff --git a/main/stasis_cache.c b/main/stasis_cache.c
index bd6d6fa..6aad67d 100644
--- a/main/stasis_cache.c
+++ b/main/stasis_cache.c
@@ -72,13 +72,9 @@
 	ast_assert(stasis_subscription_is_done(caching_topic->sub));
 
 	ao2_cleanup(caching_topic->sub);
-	caching_topic->sub = NULL;
-	ao2_cleanup(caching_topic->cache);
-	caching_topic->cache = NULL;
+	ao2_s_cleanup(&caching_topic->cache);
 	ao2_cleanup(caching_topic->topic);
-	caching_topic->topic = NULL;
-	ao2_cleanup(caching_topic->original_topic);
-	caching_topic->original_topic = NULL;
+	ao2_s_cleanup(&caching_topic->original_topic);
 }
 
 struct stasis_topic *stasis_caching_get_topic(struct stasis_caching_topic *caching_topic)
@@ -289,8 +285,7 @@
 {
 	struct stasis_cache *cache = obj;
 
-	ao2_cleanup(cache->entries);
-	cache->entries = NULL;
+	ao2_s_cleanup(&cache->entries);
 }
 
 struct stasis_cache *stasis_cache_create_full(snapshot_get_id id_fn,
@@ -305,8 +300,8 @@
 		return NULL;
 	}
 
-	cache->entries = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_RWLOCK, 0,
-		NUM_CACHE_BUCKETS, cache_entry_hash, NULL, cache_entry_cmp);
+	ao2_s_container_alloc_hash(&cache->entries, AO2_ALLOC_OPT_LOCK_RWLOCK, 0,
+		NUM_CACHE_BUCKETS, cache_entry_hash, NULL, cache_entry_cmp, "");
 	if (!cache->entries) {
 		ao2_cleanup(cache);
 		return NULL;
@@ -870,7 +865,7 @@
 
 struct stasis_caching_topic *stasis_caching_topic_create(struct stasis_topic *original_topic, struct stasis_cache *cache)
 {
-	RAII_VAR(struct stasis_caching_topic *, caching_topic, NULL, ao2_cleanup);
+	RAII_AO2_S(struct stasis_caching_topic *, caching_topic, NULL);
 	struct stasis_subscription *sub;
 	RAII_VAR(char *, new_name, NULL, ast_free);
 	int ret;
@@ -880,8 +875,8 @@
 		return NULL;
 	}
 
-	caching_topic = ao2_alloc_options(sizeof(*caching_topic),
-		stasis_caching_topic_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
+	caching_topic = ao2_alloc_full(sizeof(*caching_topic),
+		stasis_caching_topic_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK, "", &caching_topic);
 	if (caching_topic == NULL) {
 		return NULL;
 	}
@@ -891,16 +886,14 @@
 		return NULL;
 	}
 
-	ao2_ref(cache, +1);
-	caching_topic->cache = cache;
+	ao2_s_set(&caching_topic->cache, cache);
 
 	sub = internal_stasis_subscribe(original_topic, caching_topic_exec, caching_topic, 0, 0);
 	if (sub == NULL) {
 		return NULL;
 	}
 
-	ao2_ref(original_topic, +1);
-	caching_topic->original_topic = original_topic;
+	ao2_s_set(&caching_topic->original_topic, original_topic);
 
 	/* This is for the reference contained in the subscription above */
 	ao2_ref(caching_topic, +1);
diff --git a/main/stasis_message.c b/main/stasis_message.c
index 37b9a2b..71db77d 100644
--- a/main/stasis_message.c
+++ b/main/stasis_message.c
@@ -103,8 +103,8 @@
 static void stasis_message_dtor(void *obj)
 {
 	struct stasis_message *message = obj;
-	ao2_cleanup(message->type);
-	ao2_cleanup(message->data);
+	ao2_s_cleanup(&message->type);
+	ao2_s_cleanup(&message->data);
 }
 
 struct stasis_message *stasis_message_create_full(struct stasis_message_type *type, void *data, const struct ast_eid *eid)
@@ -121,10 +121,8 @@
 	}
 
 	message->timestamp = ast_tvnow();
-	ao2_ref(type, +1);
-	message->type = type;
-	ao2_ref(data, +1);
-	message->data = data;
+	ao2_s_set(&message->type, type);
+	ao2_s_set(&message->data, data);
 	if (eid) {
 		message->eid_ptr = &message->eid;
 		message->eid = *eid;
diff --git a/main/stasis_message_router.c b/main/stasis_message_router.c
index 85034bc..028ef56 100644
--- a/main/stasis_message_router.c
+++ b/main/stasis_message_router.c
@@ -210,8 +210,10 @@
 	struct stasis_topic *topic, int use_thread_pool)
 {
 	int res;
-	RAII_VAR(struct stasis_message_router *, router, NULL, ao2_cleanup);
+	RAII_AO2_S(struct stasis_message_router *, router, NULL);
 
+	router = ao2_alloc_full(sizeof(*router), router_dtor, AO2_ALLOC_OPT_LOCK_MUTEX,
+		stasis_topic_name(topic), &router);
 	router = ao2_t_alloc(sizeof(*router), router_dtor, stasis_topic_name(topic));
 	if (!router) {
 		return NULL;
diff --git a/main/threadpool.c b/main/threadpool.c
index 9cd33ab..da09d03 100644
--- a/main/threadpool.c
+++ b/main/threadpool.c
@@ -370,7 +370,7 @@
 static void threadpool_destructor(void *obj)
 {
 	struct ast_threadpool *pool = obj;
-	ao2_cleanup(pool->listener);
+	ao2_s_cleanup(&pool->listener);
 }
 
 /*
@@ -913,8 +913,7 @@
 
 	pool->tps = tps;
 	if (listener) {
-		ao2_ref(listener, +1);
-		pool->listener = listener;
+		ao2_s_set(&pool->listener, listener);
 	}
 	ast_threadpool_set_size(pool, pool->options.initial_size);
 	ao2_ref(pool, +1);
@@ -1291,10 +1290,8 @@
 {
 	struct serializer *ser = obj;
 
-	ao2_cleanup(ser->pool);
-	ser->pool = NULL;
-	ao2_cleanup(ser->shutdown_group);
-	ser->shutdown_group = NULL;
+	ao2_s_cleanup(&ser->pool);
+	ao2_s_cleanup(&ser->shutdown_group);
 }
 
 static struct serializer *serializer_create(struct ast_threadpool *pool,
@@ -1306,9 +1303,8 @@
 	if (!ser) {
 		return NULL;
 	}
-	ao2_ref(pool, +1);
-	ser->pool = pool;
-	ser->shutdown_group = ao2_bump(shutdown_group);
+	ao2_s_set(&ser->pool, pool);
+	ao2_s_set(&ser->shutdown_group, shutdown_group);
 	return ser;
 }
 
diff --git a/main/translate.c b/main/translate.c
index 8d37e37..be28257 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -297,11 +297,8 @@
 	if (t->destroy) {
 		t->destroy(pvt);
 	}
-	ao2_cleanup(pvt->f.subclass.format);
-	if (pvt->explicit_dst) {
-		ao2_ref(pvt->explicit_dst, -1);
-		pvt->explicit_dst = NULL;
-	}
+	ao2_s_cleanup(&pvt->f.subclass.format);
+	ao2_s_cleanup(&pvt->explicit_dst);
 	ast_free(pvt);
 	ast_module_unref(t->module);
 }
@@ -341,7 +338,7 @@
 	 * result of the SDP negotiation. For example with the Opus Codec, the format
 	 * knows whether both parties want to do forward-error correction (FEC).
 	 */
-	pvt->explicit_dst = ao2_bump(explicit_dst);
+	ao2_s_set(&pvt->explicit_dst, explicit_dst);
 
 	ast_module_ref(t->module);
 
@@ -366,22 +363,24 @@
 	 * C) create one.
 	 */
 	if (!pvt->f.subclass.format) {
-		pvt->f.subclass.format = ao2_bump(pvt->explicit_dst);
+		ao2_s_set(&pvt->f.subclass.format, pvt->explicit_dst);
 
 		if (!pvt->f.subclass.format && !ast_strlen_zero(pvt->t->format)) {
-			pvt->f.subclass.format = ast_format_cache_get(pvt->t->format);
+			ast_s_format_cache_get(&pvt->f.subclass.format, pvt->t->format);
 		}
 
 		if (!pvt->f.subclass.format) {
-			struct ast_codec *codec = ast_codec_get(t->dst_codec.name,
+			struct ast_codec *codec;
+
+			ast_s_codec_get(&codec, t->dst_codec.name,
 				t->dst_codec.type, t->dst_codec.sample_rate);
 			if (!codec) {
 				ast_log(LOG_ERROR, "Unable to get destination codec\n");
 				destroy(pvt);
 				return NULL;
 			}
-			pvt->f.subclass.format = ast_format_create(codec);
-			ao2_ref(codec, -1);
+			ast_s_format_create(&pvt->f.subclass.format, codec);
+			ao2_s_cleanup(&codec);
 		}
 
 		if (!pvt->f.subclass.format) {
@@ -1140,17 +1139,17 @@
 {
 	struct ast_translator *u;
 	char tmp[80];
-	RAII_VAR(struct ast_codec *, src_codec, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_codec *, dst_codec, NULL, ao2_cleanup);
+	RAII_AO2_S(struct ast_codec *, src_codec, NULL);
+	RAII_AO2_S(struct ast_codec *, dst_codec, NULL);
 
-	src_codec = ast_codec_get(t->src_codec.name, t->src_codec.type, t->src_codec.sample_rate);
+	ast_s_codec_get(&src_codec, t->src_codec.name, t->src_codec.type, t->src_codec.sample_rate);
 	if (!src_codec) {
 		ast_assert(0);
 		ast_log(LOG_WARNING, "Failed to register translator: unknown source codec %s\n", t->src_codec.name);
 		return -1;
 	}
 
-	dst_codec = ast_codec_get(t->dst_codec.name, t->dst_codec.type, t->dst_codec.sample_rate);
+	ast_s_codec_get(&dst_codec, t->dst_codec.name, t->dst_codec.type, t->dst_codec.sample_rate);
 	if (!dst_codec) {
 		ast_log(LOG_WARNING, "Failed to register translator: unknown destination codec %s\n", t->dst_codec.name);
 		return -1;

-- 
To view, visit https://gerrit.asterisk.org/3161
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic66d2e8b4267e86eaeac2fac2f88d83dbcad5bde
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Corey Farrell <git at cfware.com>



More information about the asterisk-code-review mailing list