mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-19 19:20:35 +00:00
bridge_native_rtp: Fix native bridge tech being incompatible when it should be.
When checking compatability for the native RTP bridge technology there is a race condition between clearing framehooks that are destroyed when leaving certain bridges with certain technologies (such as bridge_native_rtp) and joining bridges with the bridge_native_rtp technology. Yes, that means a channel in a native RTP bridge could move to another native RTP bridge and be considered incompatible with the new native RTP bridge causing it to revert to a simple bridge technology0. This fixes that bug by ignoring framehooks that have been marked for destruction when checking for compatibility with the bridge_native_rtp technology. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391453 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -87,7 +87,7 @@ static int native_rtp_bridge_capable(struct ast_channel *chan)
|
|||||||
{
|
{
|
||||||
if (ast_channel_monitor(chan) || (ast_channel_audiohooks(chan) &&
|
if (ast_channel_monitor(chan) || (ast_channel_audiohooks(chan) &&
|
||||||
!ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) ||
|
!ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) ||
|
||||||
!ast_framehook_list_is_empty(ast_channel_framehooks(chan))) {
|
!ast_framehook_list_contains_no_active(ast_channel_framehooks(chan))) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -222,7 +222,7 @@ struct ast_framehook_interface {
|
|||||||
* \param chan ast_channel The channel to attach the hook on to.
|
* \param chan ast_channel The channel to attach the hook on to.
|
||||||
* \param i framehook interface, The framehook's callback functions and stored data.
|
* \param i framehook interface, The framehook's callback functions and stored data.
|
||||||
*
|
*
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
*
|
*
|
||||||
* \note The data pointer is never touched by the framehook API except to
|
* \note The data pointer is never touched by the framehook API except to
|
||||||
* provide it during the event and destruction callbacks. It is entirely up to the
|
* provide it during the event and destruction callbacks. It is entirely up to the
|
||||||
@@ -237,7 +237,7 @@ int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interfac
|
|||||||
* \brief Detach an framehook from a channel.
|
* \brief Detach an framehook from a channel.
|
||||||
* \since 1.8
|
* \since 1.8
|
||||||
*
|
*
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
* If this function is never called after attaching an framehook,
|
* If this function is never called after attaching an framehook,
|
||||||
* the framehook will be detached and destroyed during channel
|
* the framehook will be detached and destroyed during channel
|
||||||
* destruction.
|
* destruction.
|
||||||
@@ -256,7 +256,7 @@ int ast_framehook_detach(struct ast_channel *chan, int framehook_id);
|
|||||||
* framehooks on a channel during channel destruction.
|
* framehooks on a channel during channel destruction.
|
||||||
* \since 1.8
|
* \since 1.8
|
||||||
*
|
*
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
*
|
*
|
||||||
* \param chan channel containing the framehook list to destroy.
|
* \param chan channel containing the framehook list to destroy.
|
||||||
* \retval 0 success
|
* \retval 0 success
|
||||||
@@ -272,7 +272,7 @@ int ast_framehook_list_destroy(struct ast_channel *chan);
|
|||||||
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
|
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
|
||||||
* framehook callback is in charge of any memory management associated with that modification.
|
* framehook callback is in charge of any memory management associated with that modification.
|
||||||
*
|
*
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
*
|
*
|
||||||
* \param framehooks list to push event to.
|
* \param framehooks list to push event to.
|
||||||
* \param frame being pushed to the framehook list.
|
* \param frame being pushed to the framehook list.
|
||||||
@@ -289,7 +289,7 @@ struct ast_frame *ast_framehook_list_read_event(struct ast_framehook_list *frame
|
|||||||
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
|
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
|
||||||
* framehook callback is in charge of any memory management associated with that modification.
|
* framehook callback is in charge of any memory management associated with that modification.
|
||||||
*
|
*
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
*
|
*
|
||||||
* \param framehooks list to push event to.
|
* \param framehooks list to push event to.
|
||||||
* \param frame being pushed to the framehook list.
|
* \param frame being pushed to the framehook list.
|
||||||
@@ -301,11 +301,26 @@ struct ast_frame *ast_framehook_list_write_event(struct ast_framehook_list *fram
|
|||||||
/*!
|
/*!
|
||||||
* \brief Determine if an framehook list is empty or not
|
* \brief Determine if an framehook list is empty or not
|
||||||
* \since 1.8
|
* \since 1.8
|
||||||
* \pre XXX The Channel must be locked during this function all.
|
* \pre The Channel must be locked during this function all.
|
||||||
*
|
*
|
||||||
* \param framehooks the framehook list
|
* \param framehooks the framehook list
|
||||||
* \retval 0, not empty
|
* \retval 0, not empty
|
||||||
* \retval 1, is empty
|
* \retval 1, is empty
|
||||||
*/
|
*/
|
||||||
int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks);
|
int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Determine if a framehook list is free of active framehooks or not
|
||||||
|
* \since 12.0.0
|
||||||
|
* \pre The channel must be locked during this function all.
|
||||||
|
*
|
||||||
|
* \param framehooks the framehook list
|
||||||
|
* \retval 0, not empty
|
||||||
|
* \retval 1, is empty (aside from dying framehooks)
|
||||||
|
*
|
||||||
|
* \note This function is very similar to ast_framehook_list_is_empty, but it checks individual
|
||||||
|
* framehooks to see if they have been marked for destruction and doesn't count them if they are.
|
||||||
|
*/
|
||||||
|
int ast_framehook_list_contains_no_active(struct ast_framehook_list *framehooks);
|
||||||
|
|
||||||
#endif /* _AST_FRAMEHOOK_H */
|
#endif /* _AST_FRAMEHOOK_H */
|
||||||
|
@@ -181,6 +181,28 @@ int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks)
|
|||||||
return AST_LIST_EMPTY(&framehooks->list) ? 1 : 0;
|
return AST_LIST_EMPTY(&framehooks->list) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_framehook_list_contains_no_active(struct ast_framehook_list *framehooks)
|
||||||
|
{
|
||||||
|
struct ast_framehook *cur;
|
||||||
|
|
||||||
|
if (!framehooks) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AST_LIST_EMPTY(&framehooks->list)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_LIST_TRAVERSE(&framehooks->list, cur, list) {
|
||||||
|
if (cur->detach_and_destroy_me) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct ast_frame *ast_framehook_list_write_event(struct ast_framehook_list *framehooks, struct ast_frame *frame)
|
struct ast_frame *ast_framehook_list_write_event(struct ast_framehook_list *framehooks, struct ast_frame *frame)
|
||||||
{
|
{
|
||||||
return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_WRITE);
|
return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_WRITE);
|
||||||
|
Reference in New Issue
Block a user