]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Properly copy/remove the device state cache flag over a masquerade.
authorWalter Doekes <walter+asterisk@wjd.nu>
Fri, 18 Oct 2013 14:40:29 +0000 (14:40 +0000)
committerWalter Doekes <walter+asterisk@wjd.nu>
Fri, 18 Oct 2013 14:40:29 +0000 (14:40 +0000)
In r378303 the AST_FLAG_DISABLE_DEVSTATE_CACHE flag was added that tells
the devstate system to not cache states for non-real devices. However,
when optimizing away channels (ast_do_masquerade), that flag wasn't
copied.

In my case, using Local devices as queue members created a situation
where the endpoint was considered in use, but the state change of the
device being available again was ignored (not cached). The endpoint
channel was optimized into the (previously) Local channel, but kept
the do-not-cache flag. The end result being that the queue member
apparently stayed in use forever.

(closes issue ASTERISK-22718)
Reported by: Walter Doekes

Review: https://reviewboard.asterisk.org/r/2925/

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

main/channel.c

index 8f59a1de108ea4f26d7b5208985b5c2f6a6b8dc1..d130c3a3dd336b5dcad8ff78e52f22830c9a42fb 100644 (file)
@@ -6504,6 +6504,8 @@ int ast_do_masquerade(struct ast_channel *original)
        int x;
        int i;
        int origstate;
+       unsigned int orig_disablestatecache;
+       unsigned int clone_disablestatecache;
        int visible_indication;
        int clone_was_zombie = 0;/*!< TRUE if the clonechan was a zombie before the masquerade. */
        struct ast_frame *current;
@@ -6728,6 +6730,20 @@ int ast_do_masquerade(struct ast_channel *original)
        original->_state = clonechan->_state;
        clonechan->_state = origstate;
 
+       /* And the swap the cachable state too. Otherwise we'd start caching
+        * Local channels and ignoring real ones. */
+       orig_disablestatecache = ast_test_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+       clone_disablestatecache = ast_test_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+       if (orig_disablestatecache != clone_disablestatecache) {
+               if (orig_disablestatecache) {
+                       ast_clear_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+                       ast_set_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+               } else {
+                       ast_set_flag(original, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+                       ast_clear_flag(clonechan, AST_FLAG_DISABLE_DEVSTATE_CACHE);
+               }
+       }
+
        /* Mangle the name of the clone channel */
        snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */
        __ast_change_name_nolink(clonechan, zombn);