Skip to content

Commit 11ad831

Browse files
authored
Synchronous port removal in audio conference bridge if port is newly added (#4253)
1 parent 1e2009d commit 11ad831

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

pjmedia/src/pjmedia/conference.c

+59
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,65 @@ PJ_DEF(pj_status_t) pjmedia_conf_remove_port( pjmedia_conf *conf,
16641664
goto on_return;
16651665
}
16661666

1667+
/* If port is new, remove it synchronously */
1668+
if (conf_port->is_new) {
1669+
pj_bool_t found = PJ_FALSE;
1670+
1671+
/* Find & cancel the add-op.
1672+
* Also cancel all following ops involving the slot.
1673+
* Note that after removed, the slot may be reused by another port
1674+
* so if not cancelled, those following ops may be applied to the
1675+
* wrong port.
1676+
*/
1677+
ope = conf->op_queue->next;
1678+
while (ope != conf->op_queue) {
1679+
op_entry* cancel_op;
1680+
1681+
cancel_op = NULL;
1682+
if (ope->type == OP_ADD_PORT && ope->param.add_port.port == port)
1683+
{
1684+
found = PJ_TRUE;
1685+
cancel_op = ope;
1686+
} else if (found && ope->type == OP_CONNECT_PORTS &&
1687+
(ope->param.connect_ports.src == port ||
1688+
ope->param.connect_ports.sink == port))
1689+
{
1690+
cancel_op = ope;
1691+
} else if (found && ope->type == OP_DISCONNECT_PORTS &&
1692+
(ope->param.disconnect_ports.src == port ||
1693+
ope->param.disconnect_ports.sink == port))
1694+
{
1695+
cancel_op = ope;
1696+
}
1697+
1698+
ope = ope->next;
1699+
1700+
/* Cancel op */
1701+
if (cancel_op) {
1702+
pj_list_erase(cancel_op);
1703+
cancel_op->type = OP_UNKNOWN;
1704+
pj_list_push_back(conf->op_queue_free, cancel_op);
1705+
}
1706+
}
1707+
1708+
/* If the add-op is not found, it may be being executed,
1709+
* do not remove it synchronously to avoid race condition.
1710+
*/
1711+
if (found) {
1712+
op_param prm;
1713+
1714+
/* Release mutex to avoid deadlock */
1715+
pj_mutex_unlock(conf->mutex);
1716+
1717+
/* Remove it */
1718+
prm.remove_port.port = port;
1719+
op_remove_port(conf, &prm);
1720+
1721+
pj_log_pop_indent();
1722+
return PJ_SUCCESS;
1723+
}
1724+
}
1725+
16671726
/* Queue the operation */
16681727
ope = get_free_op_entry(conf);
16691728
if (ope) {

0 commit comments

Comments
 (0)