[Asterisk-code-review] parking: Use channel snapshot instead of channel. (asterisk[13])

Joshua Colp asteriskteam at digium.com
Tue Nov 12 05:04:54 CST 2019


Joshua Colp has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/13173 )


Change subject: parking: Use channel snapshot instead of channel.
......................................................................

parking: Use channel snapshot instead of channel.

There exists a scenario where a thread can hold a lock on the
channels container while trying to lock a bridge. At the same
time another thread can hold the lock for said bridge while
attempting to retrieve a channel. This causes a deadlock.

This change fixes this scenario by retrieving a channel snapshot
instead of a channel, as information present in the snapshot
is all that is needed.

ASTERISK-28616

Change-Id: I68ceb1d62c7378addcd286e21be08a660a7cecf2
---
M res/parking/parking_bridge.c
1 file changed, 8 insertions(+), 8 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/73/13173/1

diff --git a/res/parking/parking_bridge.c b/res/parking/parking_bridge.c
index e61486e..5736ace 100644
--- a/res/parking/parking_bridge.c
+++ b/res/parking/parking_bridge.c
@@ -72,9 +72,9 @@
 }
 
 /* Only call this on a parked user that hasn't had its parker_dial_string set already */
-static int parked_user_set_parker_dial_string(struct parked_user *pu, struct ast_channel *parker)
+static int parked_user_set_parker_dial_string(struct parked_user *pu, struct ast_channel_snapshot *parker)
 {
-	char *dial_string = ast_strdupa(ast_channel_name(parker));
+	char *dial_string = ast_strdupa(parker->name);
 
 	ast_channel_name_to_dial_string(dial_string);
 	pu->parker_dial_string = ast_strdup(dial_string);
@@ -93,7 +93,7 @@
  *
  * \param lot The parking lot we are assigning the user to
  * \param parkee The channel being parked
- * \param parker The channel performing the park operation (may be the same channel)
+ * \param parker The snapshot of the channel performing the park operation (may be the same channel)
  * \param parker_dial_string Takes priority over parker for setting the parker dial string if included
  * \param use_random_space if true, prioritize using a random parking space instead
  *        of ${PARKINGEXTEN} and/or automatic assignment from the parking lot
@@ -106,7 +106,7 @@
  *
  * \note ao2_cleanup this reference when you are done using it or you'll cause leaks.
  */
-static struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel *parker, const char *parker_dial_string, int use_random_space, int time_limit)
+static struct parked_user *generate_parked_user(struct parking_lot *lot, struct ast_channel *chan, struct ast_channel_snapshot *parker, const char *parker_dial_string, int use_random_space, int time_limit)
 {
 	struct parked_user *new_parked_user;
 	int preferred_space = -1; /* Initialize to use parking lot defaults */
@@ -207,7 +207,7 @@
 {
 	struct parked_user *pu;
 	const char *blind_transfer;
-	RAII_VAR(struct ast_channel *, parker, NULL, ao2_cleanup); /* XXX replace with ast_channel_cleanup when available */
+	RAII_VAR(struct ast_channel_snapshot *, parker, NULL, ao2_cleanup);
 	RAII_VAR(struct park_common_datastore *, park_datastore, NULL, park_common_datastore_free);
 
 	ast_bridge_base_v_table.push(&self->base, bridge_channel, swap);
@@ -263,7 +263,7 @@
 		/* There was either a failure to apply the datastore when performing park common setup or else we had alloc failures while cloning. Abort. */
 		return -1;
 	}
-	parker = ast_channel_get_by_name(park_datastore->parker_uuid);
+	parker = ast_channel_snapshot_get_latest(park_datastore->parker_uuid);
 
 	/* If the parker and the parkee are the same channel pointer, then the channel entered using
 	 * the park application. It's possible that the channel that transferred it is still alive (particularly
@@ -272,9 +272,9 @@
 	blind_transfer = pbx_builtin_getvar_helper(bridge_channel->chan, "BLINDTRANSFER");
 	blind_transfer = ast_strdupa(S_OR(blind_transfer, ""));
 	ast_channel_unlock(bridge_channel->chan);
-	if ((!parker || parker == bridge_channel->chan)
+	if ((!parker || !strcmp(parker->name, ast_channel_name(bridge_channel->chan)))
 		&& !ast_strlen_zero(blind_transfer)) {
-		struct ast_channel *real_parker = ast_channel_get_by_name(blind_transfer);
+		struct ast_channel_snapshot *real_parker = ast_channel_snapshot_get_latest_by_name(blind_transfer);
 
 		if (real_parker) {
 			ao2_cleanup(parker);

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/13173
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Change-Id: I68ceb1d62c7378addcd286e21be08a660a7cecf2
Gerrit-Change-Number: 13173
Gerrit-PatchSet: 1
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20191112/b47ac720/attachment-0001.html>


More information about the asterisk-code-review mailing list