Confbridge: empty conference not being torn down
authorKevin Harwell <kharwell@digium.com>
Tue, 17 Sep 2013 14:58:22 +0000 (14:58 +0000)
committerKevin Harwell <kharwell@digium.com>
Tue, 17 Sep 2013 14:58:22 +0000 (14:58 +0000)
Confbridge would not properly tear down an empty conference bridge when all
users were kicked via end_marked=yes and at least one user was also set to
wait_marked.  This occurred because while end_marked users were being kicked
and at least one was also set to wait_marked then the leave wait_marked handler
would be called on that user, but there would be no waiting user (still
considered active).  The waiting users would decrement and now be negative.  The
conference would remain, but be put into an inactive state.  The solution was
to move from the active list to the wait list, those users with wait_marked set
right before kicking.  This allows both the active and wait users to decrement
correctly and the confbridge to tear down properly.

A crashed also occurred when trying to list the specific conference from the CLI.
This happened because the conference specified was invalid.  Since the
conference properly tears down now there is no way to reference it thus
alleviating the crash as well.

(closes issue ASTERISK-21859)
Reported by: Chris Gentle
Review: https://reviewboard.asterisk.org/r/2848/
........

Merged revisions 399222 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 399225 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@399226 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/confbridge/conf_state_multi_marked.c

index 0c831f8..2739be5 100644 (file)
@@ -93,8 +93,15 @@ static void leave_marked(struct confbridge_user *user)
                }
 
                AST_LIST_TRAVERSE_SAFE_BEGIN(&user->conference->active_list, user_iter, list) {
-                       /* Kick ENDMARKED cbu_iters */
+                       /* Kick ENDMARKED user_iters */
                        if (ast_test_flag(&user_iter->u_profile, USER_OPT_ENDMARKED)) {
+                               if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) &&
+                                                 !ast_test_flag(&user_iter->u_profile, USER_OPT_MARKEDUSER)) {
+                                       AST_LIST_REMOVE_CURRENT(list);
+                                       user_iter->conference->activeusers--;
+                                       AST_LIST_INSERT_TAIL(&user_iter->conference->waiting_list, user_iter, list);
+                                       user_iter->conference->waitingusers++;
+                               }
                                user_iter->kicked = 1;
                                ast_bridge_remove(user_iter->conference->bridge, user_iter->chan);
                        } else if (ast_test_flag(&user_iter->u_profile, USER_OPT_WAITMARKED) &&