summaryrefslogtreecommitdiff
path: root/main/channel.c
diff options
context:
space:
mode:
authorWalter Doekes <walter+asterisk@wjd.nu>2013-10-18 14:50:27 +0000
committerWalter Doekes <walter+asterisk@wjd.nu>2013-10-18 14:50:27 +0000
commitf33e0776ec765b92dba20ffed497688684a902bf (patch)
tree4793b5d1ff8e05f2f2656cd475afb69d06a53d15 /main/channel.c
parent42f3cae1fd3ae84b79f5b0b63d6a410be9f946eb (diff)
Properly copy/remove the device state cache flag over a masquerade.
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/ ........ Merged revisions 401178 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 401179 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 401180 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@401181 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/main/channel.c b/main/channel.c
index e6025c062..6846b84af 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -6433,6 +6433,8 @@ void ast_do_masquerade(struct ast_channel *original)
{
int x;
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. */
int clone_hold_state;
@@ -6615,6 +6617,20 @@ void ast_do_masquerade(struct ast_channel *original)
ast_channel_state_set(original, ast_channel_state(clonechan));
ast_channel_state_set(clonechan, origstate);
+ /* And the swap the cachable state too. Otherwise we'd start caching
+ * Local channels and ignoring real ones. */
+ orig_disablestatecache = ast_test_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ clone_disablestatecache = ast_test_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ if (orig_disablestatecache != clone_disablestatecache) {
+ if (orig_disablestatecache) {
+ ast_clear_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ ast_set_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ } else {
+ ast_set_flag(ast_channel_flags(original), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ ast_clear_flag(ast_channel_flags(clonechan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
+ }
+ }
+
/* Update the type. */
t_pvt = ast_channel_monitor(original);
ast_channel_monitor_set(original, ast_channel_monitor(clonechan));