From c7f2d02ef1d4e5c10987c807ecec377453bb425c Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Tue, 22 May 2012 17:29:12 +0000 Subject: Fix race condition for CEL LINKEDID_END event This patch fixes to situations that could cause the CEL LINKEDID_END event to be missed. 1) During a core stop gracefully, modules are unloaded when ast_active_channels == 0. The LINKDEDID_END event fires during the channel destructor. This means that occasionally, the cel_* module will be unloaded before the channel is destroyed. It seemed generally useful to wait until the refcount of all channels == 0 before unloading, so I added a channel counter and used it in the shutdown code. 2) During a masquerade, ast_channel_change_linkedid is called. It calls ast_cel_check_retire_linkedid which unrefs the linkedid in the linkedids container in cel.c. It didn't ref the new linkedid. Now it does. Review: https://reviewboard.asterisk.org/r/1900/ ........ Merged revisions 367292 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 367299 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@367309 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/channel_internal_api.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'main/channel_internal_api.c') diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 5125c6f59..3fc3277d0 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -423,7 +423,6 @@ DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount); DEFINE_STRINGFIELD_SETTERS_FOR(userfield); DEFINE_STRINGFIELD_SETTERS_FOR(call_forward); DEFINE_STRINGFIELD_SETTERS_FOR(uniqueid); -DEFINE_STRINGFIELD_SETTERS_FOR(linkedid); DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot); DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource); DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext); @@ -446,6 +445,12 @@ DEFINE_STRINGFIELD_GETTER_FOR(parkinglot); DEFINE_STRINGFIELD_GETTER_FOR(hangupsource); DEFINE_STRINGFIELD_GETTER_FOR(dialcontext); +void ast_channel_linkedid_set(struct ast_channel *chan, const char *value) +{ + ast_assert(!ast_strlen_zero(value)); + ast_string_field_set(chan, linkedid, value); +} + const char *ast_channel_appl(const struct ast_channel *chan) { return chan->appl; -- cgit v1.2.3