Files
asterisk/channels/chan_local.c

1454 lines
42 KiB
C
Raw Normal View History

/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 1999 - 2005, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
*
* \author Mark Spencer <markster@digium.com>
*
* \brief Local Proxy Channel
*
* \ingroup channel_drivers
*/
/*** MODULEINFO
<support_level>core</support_level>
***/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <fcntl.h>
#include <sys/signal.h>
#include "asterisk/lock.h"
#include "asterisk/causes.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/stringfields.h"
#include "asterisk/devicestate.h"
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
#include "asterisk/astobj2.h"
/*** DOCUMENTATION
<manager name="LocalOptimizeAway" language="en_US">
<synopsis>
Optimize away a local channel when possible.
</synopsis>
<syntax>
<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
<parameter name="Channel" required="true">
<para>The channel name to optimize away.</para>
</parameter>
</syntax>
<description>
<para>A local channel created with "/n" will not automatically optimize away.
Calling this command on the local channel will clear that flag and allow
it to optimize away if it's bridged or when it becomes bridged.</para>
</description>
</manager>
***/
static const char tdesc[] = "Local Proxy Channel Driver";
#define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
/* right now we are treating the locals astobj2 container as a
* list. If there is ever a reason to make this more efficient
* increasing the bucket size would help. */
static const int BUCKET_SIZE = 1;
static struct ao2_container *locals;
static struct ast_jb_conf g_jb_conf = {
.flags = 0,
.max_size = -1,
.resync_threshold = -1,
.impl = "",
.target_extra = -1,
};
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
static int local_digit_begin(struct ast_channel *ast, char digit);
2007-01-19 18:06:03 +00:00
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int local_call(struct ast_channel *ast, const char *dest, int timeout);
static int local_hangup(struct ast_channel *ast);
static int local_answer(struct ast_channel *ast);
static struct ast_frame *local_read(struct ast_channel *ast);
static int local_write(struct ast_channel *ast, struct ast_frame *f);
static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
static int local_sendtext(struct ast_channel *ast, const char *text);
static int local_devicestate(const char *data);
static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
/* PBX interface structure for channel registration */
static struct ast_channel_tech local_tech = {
.type = "Local",
.description = tdesc,
.requester = local_request,
.send_digit_begin = local_digit_begin,
.send_digit_end = local_digit_end,
.call = local_call,
.hangup = local_hangup,
.answer = local_answer,
.read = local_read,
.write = local_write,
.write_video = local_write,
.exception = local_read,
.indicate = local_indicate,
.fixup = local_fixup,
.send_html = local_sendhtml,
.send_text = local_sendtext,
.devicestate = local_devicestate,
.bridged_channel = local_bridgedchannel,
.queryoption = local_queryoption,
.setoption = local_setoption,
};
/*! \brief the local pvt structure for all channels
The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
ast_chan owner -> local_pvt -> ast_chan chan -> yet-another-pvt-depending-on-channel-type
*/
struct local_pvt {
unsigned int flags; /*!< Private flags */
char context[AST_MAX_CONTEXT]; /*!< Context to call */
char exten[AST_MAX_EXTENSION]; /*!< Extension to call */
struct ast_format_cap *reqcap; /*!< Requested format capabilities */
struct ast_jb_conf jb_conf; /*!< jitterbuffer configuration for this local channel */
struct ast_channel *owner; /*!< Master Channel - Bridging happens here */
struct ast_channel *chan; /*!< Outbound channel - PBX is run here */
struct ast_module_user *u_owner;/*!< reference to keep the module loaded while in use */
struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
};
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
#define LOCAL_ALREADY_MASQED (1 << 0) /*!< Already masqueraded */
#define LOCAL_LAUNCHED_PBX (1 << 1) /*!< PBX was launched */
#define LOCAL_NO_OPTIMIZATION (1 << 2) /*!< Do not optimize using masquerading */
#define LOCAL_BRIDGE (1 << 3) /*!< Report back the "true" channel as being bridged to */
#define LOCAL_MOH_PASSTHRU (1 << 4) /*!< Pass through music on hold start/stop frames */
/*
* \brief Send a pvt in with no locks held and get all locks
*
* \note NO locks should be held prior to calling this function
* \note The pvt must have a ref held before calling this function
* \note if outchan or outowner is set != NULL after calling this function
* those channels are locked and reffed.
* \note Batman.
*/
static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
{
struct ast_channel *chan = NULL;
struct ast_channel *owner = NULL;
for (;;) {
ao2_lock(p);
if (p->chan) {
chan = p->chan;
ast_channel_ref(chan);
}
if (p->owner) {
owner = p->owner;
ast_channel_ref(owner);
}
ao2_unlock(p);
/* if we don't have both channels, then this is very easy */
if (!owner || !chan) {
if (owner) {
ast_channel_lock(owner);
} else if(chan) {
ast_channel_lock(chan);
}
ao2_lock(p);
} else {
/* lock both channels first, then get the pvt lock */
ast_channel_lock_both(chan, owner);
ao2_lock(p);
}
/* Now that we have all the locks, validate that nothing changed */
if (p->owner != owner || p->chan != chan) {
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
}
if (chan) {
ast_channel_unlock(chan);
chan = ast_channel_unref(chan);
}
ao2_unlock(p);
continue;
}
break;
}
*outowner = p->owner;
*outchan = p->chan;
}
/* Called with ast locked */
static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
{
int res = 0;
struct local_pvt *p = NULL;
struct ast_channel *otherchan = NULL;
ast_chan_write_info_t *write_info;
if (option != AST_OPTION_CHANNEL_WRITE) {
return -1;
}
write_info = data;
if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
return -1;
}
if (!strcmp(write_info->function, "CHANNEL")
&& !strncasecmp(write_info->data, "hangup_handler_", 15)) {
/* Block CHANNEL(hangup_handler_xxx) writes to the other local channel. */
return 0;
}
/* get the tech pvt */
if (!(p = ast_channel_tech_pvt(ast))) {
return -1;
}
ao2_ref(p, 1);
ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
/* get the channel we are supposed to write to */
ao2_lock(p);
otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
if (!otherchan || otherchan == write_info->chan) {
res = -1;
otherchan = NULL;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
goto setoption_cleanup;
}
ast_channel_ref(otherchan);
/* clear the pvt lock before grabbing the channel */
ao2_unlock(p);
ast_channel_lock(otherchan);
res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
ast_channel_unlock(otherchan);
setoption_cleanup:
if (p) {
ao2_ref(p, -1);
}
if (otherchan) {
ast_channel_unref(otherchan);
}
ast_channel_lock(ast); /* Lock back before we leave */
return res;
}
/*! \brief Adds devicestate to local channels */
static int local_devicestate(const char *data)
{
char *exten = ast_strdupa(data);
char *context = NULL, *opts = NULL;
int res;
struct local_pvt *lp;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
struct ao2_iterator it;
if (!(context = strchr(exten, '@'))) {
ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
return AST_DEVICE_INVALID;
}
*context++ = '\0';
/* Strip options if they exist */
if ((opts = strchr(context, '/')))
*opts = '\0';
ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
res = ast_exists_extension(NULL, context, exten, 1, NULL);
if (!res)
return AST_DEVICE_INVALID;
res = AST_DEVICE_NOT_INUSE;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
it = ao2_iterator_init(locals, 0);
while ((lp = ao2_iterator_next(&it))) {
if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
res = AST_DEVICE_INUSE;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(lp, -1);
break;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(lp, -1);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_iterator_destroy(&it);
return res;
}
/*! \brief Return the bridged channel of a Local channel */
static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
{
struct local_pvt *p = ast_channel_tech_pvt(bridge);
struct ast_channel *bridged = bridge;
if (!p) {
ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
Replace direct access to channel name with accessor functions There are many benefits to making the ast_channel an opaque handle, from increasing maintainability to presenting ways to kill masquerades. This patch kicks things off by taking things a field at a time, renaming the field to '__do_not_use_${fieldname}' and then writing setters/getters and converting the existing code to using them. When all fields are done, we can move ast_channel to a C file from channel.h and lop off the '__do_not_use_'. This patch sets up main/channel_interal_api.c to be the only file that actually accesses the ast_channel's fields directly. The intent would be for any API functions in channel.c to use the accessor functions. No more monkeying around with channel internals. We should use our own APIs. The interesting changes in this patch are the addition of channel_internal_api.c, the moving of the AST_DATA stuff from channel.c to channel_internal_api.c (note: the AST_DATA stuff will have to be reworked to use accessor functions when ast_channel is really opaque), and some re-working of the way channel iterators/callbacks are handled so as to avoid creating fake ast_channels on the stack to pass in matching data by directly accessing fields (since "name" is a stringfield and the fake channel doesn't init the stringfields, you can't use the ast_channel_name_set() function). I went with ast_channel_name(chan) for a getter, and ast_channel_name_set(chan, name) for a setter. The majority of the grunt-work for this change was done by writing a semantic patch using Coccinelle ( http://coccinelle.lip6.fr/ ). Review: https://reviewboard.asterisk.org/r/1655/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@350223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-09 22:15:50 +00:00
ast_channel_name(chan), ast_channel_name(bridge));
return NULL;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
if (ast_test_flag(p, LOCAL_BRIDGE)) {
/* Find the opposite channel */
bridged = (bridge == p->owner ? p->chan : p->owner);
/* Now see if the opposite channel is bridged to anything */
if (!bridged) {
bridged = bridge;
} else if (ast_channel_internal_bridged_channel(bridged)) {
bridged = ast_channel_internal_bridged_channel(bridged);
}
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
return bridged;
}
/* Called with ast locked */
static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
{
struct local_pvt *p;
struct ast_channel *bridged = NULL;
struct ast_channel *tmp = NULL;
int res = 0;
if (option != AST_OPTION_T38_STATE) {
/* AST_OPTION_T38_STATE is the only supported option at this time */
return -1;
}
/* for some reason the channel is not locked in channel.c when this function is called */
if (!(p = ast_channel_tech_pvt(ast))) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) {
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
return -1;
}
ast_channel_ref(tmp);
ao2_unlock(p);
ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
ast_channel_lock(tmp);
if (!(bridged = ast_bridged_channel(tmp))) {
res = -1;
ast_channel_unlock(tmp);
goto query_cleanup;
}
ast_channel_ref(bridged);
ast_channel_unlock(tmp);
query_cleanup:
if (bridged) {
res = ast_channel_queryoption(bridged, option, data, datalen, 0);
bridged = ast_channel_unref(bridged);
}
if (tmp) {
tmp = ast_channel_unref(tmp);
}
ast_channel_lock(ast); /* Lock back before we leave */
return res;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
/*! \brief queue a frame on a to either the p->owner or p->chan
*
* \note the local_pvt MUST have it's ref count bumped before entering this function and
* decremented after this function is called. This is a side effect of the deadlock
* avoidance that is necessary to lock 2 channels and a tech_pvt. Without a ref counted
* local_pvt, it is impossible to guarantee it will not be destroyed by another thread
* during deadlock avoidance.
*/
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f,
Merged revisions 116038 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r116038 | russell | 2008-05-13 16:17:23 -0500 (Tue, 13 May 2008) | 24 lines Fix a deadlock involving channel autoservice and chan_local that was debugged and fixed by mmichelson and me. We observed a system that had a bunch of threads stuck in ast_autoservice_stop(). The reason these threads were waiting around is because this function waits to ensure that the channel list in the autoservice thread gets rebuilt before the stop() function returns. However, the autoservice thread was also locked, so the autoservice channel list was never getting rebuilt. The autoservice thread was stuck waiting for the channel lock on a local channel. However, the local channel was locked by a thread that was stuck in the autoservice stop function. It turned out that the issue came down to the local_queue_frame() function in chan_local. This function assumed that one of the channels passed in as an argument was locked when called. However, that was not always the case. There were multiple cases in which this channel was not locked when the function was called. We fixed up chan_local to indicate to this function whether this channel was locked or not. The previous assumption had caused local_queue_frame() to improperly return with the channel locked, where it would then never get unlocked. (closes issue #12584) (related to issue #12603) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@116039 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2008-05-13 21:18:55 +00:00
struct ast_channel *us, int us_locked)
{
struct ast_channel *other = NULL;
/* Recalculate outbound channel */
other = isoutbound ? p->owner : p->chan;
if (!other) {
return 0;
}
/* do not queue frame if generator is on both local channels */
if (us && ast_channel_generator(us) && ast_channel_generator(other)) {
return 0;
}
/* grab a ref on the channel before unlocking the pvt,
* other can not go away from us now regardless of locking */
ast_channel_ref(other);
if (us && us_locked) {
ast_channel_unlock(us);
}
ao2_unlock(p);
if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
ast_setstate(other, AST_STATE_RINGING);
}
ast_queue_frame(other, f);
other = ast_channel_unref(other);
if (us && us_locked) {
ast_channel_lock(us);
}
ao2_lock(p);
return 0;
}
static int local_answer(struct ast_channel *ast)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int isoutbound;
int res = -1;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
ao2_ref(p, 1);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {
/* Pass along answer since somebody answered us */
struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
Merged revisions 116038 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r116038 | russell | 2008-05-13 16:17:23 -0500 (Tue, 13 May 2008) | 24 lines Fix a deadlock involving channel autoservice and chan_local that was debugged and fixed by mmichelson and me. We observed a system that had a bunch of threads stuck in ast_autoservice_stop(). The reason these threads were waiting around is because this function waits to ensure that the channel list in the autoservice thread gets rebuilt before the stop() function returns. However, the autoservice thread was also locked, so the autoservice channel list was never getting rebuilt. The autoservice thread was stuck waiting for the channel lock on a local channel. However, the local channel was locked by a thread that was stuck in the autoservice stop function. It turned out that the issue came down to the local_queue_frame() function in chan_local. This function assumed that one of the channels passed in as an argument was locked when called. However, that was not always the case. There were multiple cases in which this channel was not locked when the function was called. We fixed up chan_local to indicate to this function whether this channel was locked or not. The previous assumption had caused local_queue_frame() to improperly return with the channel locked, where it would then never get unlocked. (closes issue #12584) (related to issue #12603) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@116039 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2008-05-13 21:18:55 +00:00
res = local_queue_frame(p, isoutbound, &answer, ast, 1);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
} else {
ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n");
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
/*!
* \internal
* \note This function assumes that we're only called from the "outbound" local channel side
*
* \note it is assummed p is locked and reffed before entering this function
*/
static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
{
struct ast_channel *owner;
struct ast_channel *chan;
struct ast_channel *bridged_chan;
struct ast_frame *f;
/* Do a few conditional checks early on just to see if this optimization is possible */
if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
|| !p->chan || !p->owner) {
return;
}
/* Safely get the channel bridged to p->chan */
chan = ast_channel_ref(p->chan);
ao2_unlock(p); /* don't call bridged channel with the pvt locked */
bridged_chan = ast_bridged_channel(chan);
ao2_lock(p);
chan = ast_channel_unref(chan);
/* since we had to unlock p to get the bridged chan, validate our
* data once again and verify the bridged channel is what we expect
* it to be in order to perform this optimization */
if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION | LOCAL_ALREADY_MASQED)
|| !p->chan || !p->owner
|| (ast_channel_internal_bridged_channel(p->chan) != bridged_chan)) {
return;
}
/* only do the masquerade if we are being called on the outbound channel,
if it has been bridged to another channel and if there are no pending
frames on the owner channel (because they would be transferred to the
outbound channel during the masquerade)
*/
if (!ast_channel_internal_bridged_channel(p->chan) /* Not ast_bridged_channel! Only go one step! */
|| !AST_LIST_EMPTY(ast_channel_readq(p->owner))
|| ast != p->chan /* Sanity check (should always be false) */) {
return;
}
/* Masquerade bridged channel into owner */
/* Lock everything we need, one by one, and give up if
we can't get everything. Remember, we'll get another
chance in just a little bit */
if (ast_channel_trylock(ast_channel_internal_bridged_channel(p->chan))) {
return;
}
if (ast_check_hangup(ast_channel_internal_bridged_channel(p->chan))
|| ast_channel_trylock(p->owner)) {
ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
return;
}
/*
* At this point we have 4 locks:
* p, p->chan (same as ast), p->chan->_bridge, p->owner
*
* Flush a voice or video frame on the outbound channel to make
* the queue empty faster so we can get optimized out.
*/
f = AST_LIST_FIRST(ast_channel_readq(p->chan));
if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
AST_LIST_REMOVE_HEAD(ast_channel_readq(p->chan), frame_list);
ast_frfree(f);
f = AST_LIST_FIRST(ast_channel_readq(p->chan));
}
if (f
|| ast_check_hangup(p->owner)
|| ast_channel_masquerade(p->owner, ast_channel_internal_bridged_channel(p->chan))) {
ast_channel_unlock(p->owner);
ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
return;
}
/* Masquerade got setup. */
ast_debug(4, "Masquerading %s <- %s\n",
ast_channel_name(p->owner),
ast_channel_name(ast_channel_internal_bridged_channel(p->chan)));
if (ast_channel_monitor(p->owner)
&& !ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan))) {
struct ast_channel_monitor *tmp;
/* If a local channel is being monitored, we don't want a masquerade
* to cause the monitor to go away. Since the masquerade swaps the monitors,
* pre-swapping the monitors before the masquerade will ensure that the monitor
* ends up where it is expected.
*/
tmp = ast_channel_monitor(p->owner);
ast_channel_monitor_set(p->owner, ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan)));
ast_channel_monitor_set(ast_channel_internal_bridged_channel(p->chan), tmp);
}
if (ast_channel_audiohooks(p->chan)) {
struct ast_audiohook_list *audiohooks_swapper;
audiohooks_swapper = ast_channel_audiohooks(p->chan);
ast_channel_audiohooks_set(p->chan, ast_channel_audiohooks(p->owner));
ast_channel_audiohooks_set(p->owner, audiohooks_swapper);
}
/* If any Caller ID was set, preserve it after masquerade like above. We must check
* to see if Caller ID was set because otherwise we'll mistakingly copy info not
* set from the dialplan and will overwrite the real channel Caller ID. The reason
* for this whole preswapping action is because the Caller ID is set on the channel
* thread (which is the to be masqueraded away local channel) before both local
* channels are optimized away.
*/
if (ast_channel_caller(p->owner)->id.name.valid || ast_channel_caller(p->owner)->id.number.valid
|| ast_channel_caller(p->owner)->id.subaddress.valid || ast_channel_caller(p->owner)->ani.name.valid
|| ast_channel_caller(p->owner)->ani.number.valid || ast_channel_caller(p->owner)->ani.subaddress.valid) {
SWAP(*ast_channel_caller(p->owner), *ast_channel_caller(ast_channel_internal_bridged_channel(p->chan)));
}
if (ast_channel_redirecting(p->owner)->from.name.valid || ast_channel_redirecting(p->owner)->from.number.valid
|| ast_channel_redirecting(p->owner)->from.subaddress.valid || ast_channel_redirecting(p->owner)->to.name.valid
|| ast_channel_redirecting(p->owner)->to.number.valid || ast_channel_redirecting(p->owner)->to.subaddress.valid) {
SWAP(*ast_channel_redirecting(p->owner), *ast_channel_redirecting(ast_channel_internal_bridged_channel(p->chan)));
}
if (ast_channel_dialed(p->owner)->number.str || ast_channel_dialed(p->owner)->subaddress.valid) {
SWAP(*ast_channel_dialed(p->owner), *ast_channel_dialed(ast_channel_internal_bridged_channel(p->chan)));
}
ast_app_group_update(p->chan, p->owner);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
ast_channel_unlock(p->owner);
ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
/* Do the masquerade now. */
owner = ast_channel_ref(p->owner);
ao2_unlock(p);
ast_channel_unlock(ast);
ast_do_masquerade(owner);
ast_channel_unref(owner);
ast_channel_lock(ast);
ao2_lock(p);
}
static struct ast_frame *local_read(struct ast_channel *ast)
{
return &ast_null_frame;
}
static int local_write(struct ast_channel *ast, struct ast_frame *f)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = -1;
int isoutbound;
if (!p) {
return -1;
}
/* Just queue for delivery to the other side */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, 1); /* ref for local_queue_frame */
ao2_lock(p);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound
&& (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
check_bridge(ast, p);
}
if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) {
Merged revisions 116038 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r116038 | russell | 2008-05-13 16:17:23 -0500 (Tue, 13 May 2008) | 24 lines Fix a deadlock involving channel autoservice and chan_local that was debugged and fixed by mmichelson and me. We observed a system that had a bunch of threads stuck in ast_autoservice_stop(). The reason these threads were waiting around is because this function waits to ensure that the channel list in the autoservice thread gets rebuilt before the stop() function returns. However, the autoservice thread was also locked, so the autoservice channel list was never getting rebuilt. The autoservice thread was stuck waiting for the channel lock on a local channel. However, the local channel was locked by a thread that was stuck in the autoservice stop function. It turned out that the issue came down to the local_queue_frame() function in chan_local. This function assumed that one of the channels passed in as an argument was locked when called. However, that was not always the case. There were multiple cases in which this channel was not locked when the function was called. We fixed up chan_local to indicate to this function whether this channel was locked or not. The previous assumption had caused local_queue_frame() to improperly return with the channel locked, where it would then never get unlocked. (closes issue #12584) (related to issue #12603) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@116039 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2008-05-13 21:18:55 +00:00
res = local_queue_frame(p, isoutbound, f, ast, 1);
} else {
ast_debug(1, "Not posting to '%s' queue since already masqueraded out\n",
ast_channel_name(ast));
res = 0;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
{
struct local_pvt *p = ast_channel_tech_pvt(newchan);
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
if ((p->owner != oldchan) && (p->chan != oldchan)) {
ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
return -1;
}
if (p->owner == oldchan) {
p->owner = newchan;
} else {
p->chan = newchan;
}
/* Do not let a masquerade cause a Local channel to be bridged to itself! */
if (!ast_check_hangup(newchan) && ((p->owner && ast_channel_internal_bridged_channel(p->owner) == p->chan) || (p->chan && ast_channel_internal_bridged_channel(p->chan) == p->owner))) {
ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
ast_queue_hangup(newchan);
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
return 0;
}
static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = 0;
struct ast_frame f = { AST_FRAME_CONTROL, };
int isoutbound;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, 1); /* ref for local_queue_frame */
/* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
ast_moh_start(ast, data, NULL);
} else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
ast_moh_stop(ast);
} else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
struct ast_channel *this_channel;
struct ast_channel *the_other_channel;
/* A connected line update frame may only contain a partial amount of data, such
* as just a source, or just a ton, and not the full amount of information. However,
* the collected information is all stored in the outgoing channel's connectedline
* structure, so when receiving a connected line update on an outgoing local channel,
* we need to transmit the collected connected line information instead of whatever
* happens to be in this control frame. The same applies for redirecting information, which
* is why it is handled here as well.*/
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
isoutbound = IS_OUTBOUND(ast, p);
if (isoutbound) {
this_channel = p->chan;
the_other_channel = p->owner;
} else {
this_channel = p->owner;
the_other_channel = p->chan;
}
if (the_other_channel) {
unsigned char frame_data[1024];
if (condition == AST_CONTROL_CONNECTED_LINE) {
Enhancements to connected line and redirecting work. From reviewboard: Digium has a commercial customer who has made extensive use of the connected party and redirecting information present in later versions of Asterisk Business Edition and which is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions have come about. This patch adds several enhancements to maximize usage of the connected party and redirecting information functionality. First, Asterisk trunk already had connected line interception macros. These macros allow you to manipulate connected line information before it was sent out to its target. This patch adds the same feature except for redirecting information instead. Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI, mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is that it can be set to whatever value the administrator likes. Later, when running connected line and redirecting macros, the admin can read the tag off the appropriate structure to determine what action to take. You can think of this sort of like a channel variable, except that instead of having the variable associated with a channel, the variable is associated with a specific identity within Asterisk. Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force a specific calling presentation value on the outgoing channel. Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party being transferred would not have the opportunity to run a connected line interception macro to possibly alter the transfer target's connected line information. The issue here was that during a blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line update. The way this was corrected was to add this new control frame subclass. Now, we queue an AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should be run. When ast_read is called to read the frame, ast_read responds by calling a callback function associated with the specific read action the control frame describes. In this case, the action taken is to run the connected line interception macro on the transferee's channel. Review: https://reviewboard.asterisk.org/r/652/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-05-17 15:36:31 +00:00
if (isoutbound) {
ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
Enhancements to connected line and redirecting work. From reviewboard: Digium has a commercial customer who has made extensive use of the connected party and redirecting information present in later versions of Asterisk Business Edition and which is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions have come about. This patch adds several enhancements to maximize usage of the connected party and redirecting information functionality. First, Asterisk trunk already had connected line interception macros. These macros allow you to manipulate connected line information before it was sent out to its target. This patch adds the same feature except for redirecting information instead. Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI, mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is that it can be set to whatever value the administrator likes. Later, when running connected line and redirecting macros, the admin can read the tag off the appropriate structure to determine what action to take. You can think of this sort of like a channel variable, except that instead of having the variable associated with a channel, the variable is associated with a specific identity within Asterisk. Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force a specific calling presentation value on the outgoing channel. Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party being transferred would not have the opportunity to run a connected line interception macro to possibly alter the transfer target's connected line information. The issue here was that during a blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line update. The way this was corrected was to add this new control frame subclass. Now, we queue an AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should be run. When ast_read is called to read the frame, ast_read responds by calling a callback function associated with the specific read action the control frame describes. In this case, the action taken is to run the connected line interception macro on the transferee's channel. Review: https://reviewboard.asterisk.org/r/652/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-05-17 15:36:31 +00:00
}
f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), ast_channel_connected(this_channel), NULL);
} else {
f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), ast_channel_redirecting(this_channel), NULL);
}
f.subclass.integer = condition;
f.data.ptr = frame_data;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
res = local_queue_frame(p, isoutbound, &f, ast, 1);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
} else {
/* Queue up a frame representing the indication as a control frame */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
/*
* Block -1 stop tones events if we are to be optimized out. We
* don't need a flurry of these events on a local channel chain
* when initially connected to slow the optimization process.
*/
if (0 <= condition || ast_test_flag(p, LOCAL_NO_OPTIMIZATION)) {
isoutbound = IS_OUTBOUND(ast, p);
f.subclass.integer = condition;
f.data.ptr = (void *) data;
f.datalen = datalen;
res = local_queue_frame(p, isoutbound, &f, ast, 1);
} else {
ast_debug(4, "Blocked indication %d\n", condition);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, -1);
return res;
}
static int local_digit_begin(struct ast_channel *ast, char digit)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = -1;
struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
int isoutbound;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, 1); /* ref for local_queue_frame */
ao2_lock(p);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass.integer = digit;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
res = local_queue_frame(p, isoutbound, &f, ast, 0);
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
2007-01-19 18:06:03 +00:00
static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = -1;
struct ast_frame f = { AST_FRAME_DTMF_END, };
int isoutbound;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, 1); /* ref for local_queue_frame */
ao2_lock(p);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass.integer = digit;
2007-01-19 18:06:03 +00:00
f.len = duration;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
res = local_queue_frame(p, isoutbound, &f, ast, 0);
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
static int local_sendtext(struct ast_channel *ast, const char *text)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = -1;
struct ast_frame f = { AST_FRAME_TEXT, };
int isoutbound;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
ao2_ref(p, 1); /* ref for local_queue_frame */
isoutbound = IS_OUTBOUND(ast, p);
f.data.ptr = (char *) text;
f.datalen = strlen(text) + 1;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
res = local_queue_frame(p, isoutbound, &f, ast, 0);
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int res = -1;
struct ast_frame f = { AST_FRAME_HTML, };
int isoutbound;
if (!p) {
return -1;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(p);
ao2_ref(p, 1); /* ref for local_queue_frame */
isoutbound = IS_OUTBOUND(ast, p);
f.subclass.integer = subclass;
f.data.ptr = (char *)data;
f.datalen = datalen;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
res = local_queue_frame(p, isoutbound, &f, ast, 0);
ao2_unlock(p);
ao2_ref(p, -1);
return res;
}
/*! \brief Initiate new call, part of PBX interface
* dest is the dial string */
static int local_call(struct ast_channel *ast, const char *dest, int timeout)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int pvt_locked = 0;
struct ast_channel *owner = NULL;
struct ast_channel *chan = NULL;
int res;
struct ast_var_t *varptr;
struct ast_var_t *clone_var;
Merge Call completion support into trunk. From Reviewboard: CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date overview of the architecture can be found in the file doc/CCSS_architecture.pdf in the CCSS branch. Off the top of my head, the big differences between what is implemented and what is in the document are as follows: 1. We did not end up modifying the Hangup application at all. 2. The document states that a single call completion monitor may be used across multiple calls to the same device. This proved to not be such a good idea when implementing protocol-specific monitors, and so we ended up using one monitor per-device per-call. 3. There are some configuration options which were conceived after the document was written. These are documented in the ccss.conf.sample that is on this review request. For some basic understanding of terminology used throughout this code, see the ccss.tex document that is on this review. This implements CCBS and CCNR in several flavors. First up is a "generic" implementation, which can work over any channel technology provided that the channel technology can accurately report device state. Call completion is requested using the dialplan application CallCompletionRequest and can be canceled using CallCompletionCancel. Device state subscriptions are used in order to monitor the state of called parties. Next, there is a SIP-specific implementation of call completion. This method uses the methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion using SIP signaling. There are a few things to note here: * The agent/monitor terminology used throughout Asterisk sometimes is the reverse of what is defined in the referenced draft. * Implementation of the draft required support for SIP PUBLISH. I attempted to write this in a generic-enough fashion such that if someone were to want to write PUBLISH support for other event packages, such as dialog-state or presence, most of the effort would be in writing callbacks specific to the event package. * A subportion of supporting PUBLISH reception was that we had to implement a PIDF parser. The PIDF support added is a bit minimal. I first wrote a validation routine to ensure that the PIDF document is formatted properly. The rest of the PIDF reading is done in-line in the call-completion-specific PUBLISH-handling code. In other words, while there is PIDF support here, it is not in any state where it could easily be applied to other event packages as is. Finally, there are a variety of ISDN-related call completion protocols supported. These were written by Richard Mudgett, and as such I can't really say much about their implementation. There are notes in the CHANGES file that indicate the ISDN protocols over which call completion is supported. Review: https://reviewboard.asterisk.org/r/523 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-04-09 15:31:32 +00:00
char *reduced_dest = ast_strdupa(dest);
char *slash;
const char *exten;
const char *context;
if (!p) {
return -1;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
/* since we are letting go of channel locks that were locked coming into
* this function, then we need to give the tech pvt a ref */
ao2_ref(p, 1);
ast_channel_unlock(ast);
awesome_locking(p, &chan, &owner);
pvt_locked = 1;
if (owner != ast) {
res = -1;
goto return_cleanup;
}
if (!owner || !chan) {
res = -1;
goto return_cleanup;
}
/*
* Note that cid_num and cid_name aren't passed in the ast_channel_alloc
* call, so it's done here instead.
*
* All these failure points just return -1. The individual strings will
* be cleared when we destroy the channel.
*/
ast_party_redirecting_copy(ast_channel_redirecting(chan), ast_channel_redirecting(owner));
ast_party_dialed_copy(ast_channel_dialed(chan), ast_channel_dialed(owner));
ast_connected_line_copy_to_caller(ast_channel_caller(chan), ast_channel_connected(owner));
ast_connected_line_copy_from_caller(ast_channel_connected(chan), ast_channel_caller(owner));
ast_channel_language_set(chan, ast_channel_language(owner));
ast_channel_accountcode_set(chan, ast_channel_accountcode(owner));
ast_channel_musicclass_set(chan, ast_channel_musicclass(owner));
ast_cdr_update(chan);
Merged revisions 7265-7266,7268-7275 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines Changing bug report address to the Asterisk issue tracker ........ r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines Makefile 'update' target now supports updating from Subversion repositories (issue #5875) remove support for 'patches' subdirectory, it's no longer useful ........ r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines ensure channel's scheduling context is freed (issue #5788) ........ r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines don't block waiting for the Festival server forever when it goes away (issue #5882) ........ r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines allow variables to exist on both 'halves' of the Local channel (issue #5810) ........ r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879) ........ r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870) reformat password changing code to conform to coding guidelines (issue #5870) ........ r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines allow previous context-searching behavior to be used if desired (issue #5899) ........ r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines inherit channel variables into channels created by Page() application (issue #5888) ........ r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-12-02 01:01:11 +00:00
ast_channel_cc_params_init(chan, ast_channel_get_cc_config_params(owner));
Merge Call completion support into trunk. From Reviewboard: CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date overview of the architecture can be found in the file doc/CCSS_architecture.pdf in the CCSS branch. Off the top of my head, the big differences between what is implemented and what is in the document are as follows: 1. We did not end up modifying the Hangup application at all. 2. The document states that a single call completion monitor may be used across multiple calls to the same device. This proved to not be such a good idea when implementing protocol-specific monitors, and so we ended up using one monitor per-device per-call. 3. There are some configuration options which were conceived after the document was written. These are documented in the ccss.conf.sample that is on this review request. For some basic understanding of terminology used throughout this code, see the ccss.tex document that is on this review. This implements CCBS and CCNR in several flavors. First up is a "generic" implementation, which can work over any channel technology provided that the channel technology can accurately report device state. Call completion is requested using the dialplan application CallCompletionRequest and can be canceled using CallCompletionCancel. Device state subscriptions are used in order to monitor the state of called parties. Next, there is a SIP-specific implementation of call completion. This method uses the methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion using SIP signaling. There are a few things to note here: * The agent/monitor terminology used throughout Asterisk sometimes is the reverse of what is defined in the referenced draft. * Implementation of the draft required support for SIP PUBLISH. I attempted to write this in a generic-enough fashion such that if someone were to want to write PUBLISH support for other event packages, such as dialog-state or presence, most of the effort would be in writing callbacks specific to the event package. * A subportion of supporting PUBLISH reception was that we had to implement a PIDF parser. The PIDF support added is a bit minimal. I first wrote a validation routine to ensure that the PIDF document is formatted properly. The rest of the PIDF reading is done in-line in the call-completion-specific PUBLISH-handling code. In other words, while there is PIDF support here, it is not in any state where it could easily be applied to other event packages as is. Finally, there are a variety of ISDN-related call completion protocols supported. These were written by Richard Mudgett, and as such I can't really say much about their implementation. There are notes in the CHANGES file that indicate the ISDN protocols over which call completion is supported. Review: https://reviewboard.asterisk.org/r/523 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-04-09 15:31:32 +00:00
/* Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's set on the queue/dial call request in the dialplan */
if (ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
ast_channel_hangupcause_set(chan, AST_CAUSE_ANSWERED_ELSEWHERE);
}
Merged revisions 7265-7266,7268-7275 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines Changing bug report address to the Asterisk issue tracker ........ r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines Makefile 'update' target now supports updating from Subversion repositories (issue #5875) remove support for 'patches' subdirectory, it's no longer useful ........ r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines ensure channel's scheduling context is freed (issue #5788) ........ r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines don't block waiting for the Festival server forever when it goes away (issue #5882) ........ r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines allow variables to exist on both 'halves' of the Local channel (issue #5810) ........ r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879) ........ r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870) reformat password changing code to conform to coding guidelines (issue #5870) ........ r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines allow previous context-searching behavior to be used if desired (issue #5899) ........ r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines inherit channel variables into channels created by Page() application (issue #5888) ........ r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-12-02 01:01:11 +00:00
/* copy the channel variables from the incoming channel to the outgoing channel */
/* Note that due to certain assumptions, they MUST be in the same order */
AST_LIST_TRAVERSE(ast_channel_varshead(owner), varptr, entries) {
clone_var = ast_var_assign(varptr->name, varptr->value);
if (clone_var) {
AST_LIST_INSERT_TAIL(ast_channel_varshead(chan), clone_var, entries);
Merged revisions 7265-7266,7268-7275 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines Changing bug report address to the Asterisk issue tracker ........ r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines Makefile 'update' target now supports updating from Subversion repositories (issue #5875) remove support for 'patches' subdirectory, it's no longer useful ........ r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines ensure channel's scheduling context is freed (issue #5788) ........ r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines don't block waiting for the Festival server forever when it goes away (issue #5882) ........ r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines allow variables to exist on both 'halves' of the Local channel (issue #5810) ........ r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879) ........ r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870) reformat password changing code to conform to coding guidelines (issue #5870) ........ r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines allow previous context-searching behavior to be used if desired (issue #5899) ........ r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines inherit channel variables into channels created by Page() application (issue #5888) ........ r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-12-02 01:01:11 +00:00
}
}
ast_channel_datastore_inherit(owner, chan);
Merge Call completion support into trunk. From Reviewboard: CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date overview of the architecture can be found in the file doc/CCSS_architecture.pdf in the CCSS branch. Off the top of my head, the big differences between what is implemented and what is in the document are as follows: 1. We did not end up modifying the Hangup application at all. 2. The document states that a single call completion monitor may be used across multiple calls to the same device. This proved to not be such a good idea when implementing protocol-specific monitors, and so we ended up using one monitor per-device per-call. 3. There are some configuration options which were conceived after the document was written. These are documented in the ccss.conf.sample that is on this review request. For some basic understanding of terminology used throughout this code, see the ccss.tex document that is on this review. This implements CCBS and CCNR in several flavors. First up is a "generic" implementation, which can work over any channel technology provided that the channel technology can accurately report device state. Call completion is requested using the dialplan application CallCompletionRequest and can be canceled using CallCompletionCancel. Device state subscriptions are used in order to monitor the state of called parties. Next, there is a SIP-specific implementation of call completion. This method uses the methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion using SIP signaling. There are a few things to note here: * The agent/monitor terminology used throughout Asterisk sometimes is the reverse of what is defined in the referenced draft. * Implementation of the draft required support for SIP PUBLISH. I attempted to write this in a generic-enough fashion such that if someone were to want to write PUBLISH support for other event packages, such as dialog-state or presence, most of the effort would be in writing callbacks specific to the event package. * A subportion of supporting PUBLISH reception was that we had to implement a PIDF parser. The PIDF support added is a bit minimal. I first wrote a validation routine to ensure that the PIDF document is formatted properly. The rest of the PIDF reading is done in-line in the call-completion-specific PUBLISH-handling code. In other words, while there is PIDF support here, it is not in any state where it could easily be applied to other event packages as is. Finally, there are a variety of ISDN-related call completion protocols supported. These were written by Richard Mudgett, and as such I can't really say much about their implementation. There are notes in the CHANGES file that indicate the ISDN protocols over which call completion is supported. Review: https://reviewboard.asterisk.org/r/523 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-04-09 15:31:32 +00:00
/* If the local channel has /n or /b on the end of it,
* we need to lop that off for our argument to setting
* up the CC_INTERFACES variable
*/
if ((slash = strrchr(reduced_dest, '/'))) {
*slash = '\0';
}
ast_set_cc_interfaces_chanvar(chan, reduced_dest);
Merged revisions 7265-7266,7268-7275 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.2 ........ r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines Changing bug report address to the Asterisk issue tracker ........ r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines Makefile 'update' target now supports updating from Subversion repositories (issue #5875) remove support for 'patches' subdirectory, it's no longer useful ........ r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines ensure channel's scheduling context is freed (issue #5788) ........ r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines don't block waiting for the Festival server forever when it goes away (issue #5882) ........ r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines allow variables to exist on both 'halves' of the Local channel (issue #5810) ........ r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879) ........ r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870) reformat password changing code to conform to coding guidelines (issue #5870) ........ r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines allow previous context-searching behavior to be used if desired (issue #5899) ........ r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines inherit channel variables into channels created by Page() application (issue #5888) ........ r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-12-02 01:01:11 +00:00
exten = ast_strdupa(ast_channel_exten(chan));
context = ast_strdupa(ast_channel_context(chan));
ao2_unlock(p);
pvt_locked = 0;
ast_channel_unlock(chan);
if (!ast_exists_extension(chan, context, exten, 1,
S_COR(ast_channel_caller(owner)->id.number.valid, ast_channel_caller(owner)->id.number.str, NULL))) {
ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
res = -1;
chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
goto return_cleanup;
}
/*** DOCUMENTATION
<managerEventInstance>
<synopsis>Raised when two halves of a Local Channel form a bridge.</synopsis>
<syntax>
<parameter name="Channel1">
<para>The name of the Local Channel half that bridges to another channel.</para>
</parameter>
<parameter name="Channel2">
<para>The name of the Local Channel half that executes the dialplan.</para>
</parameter>
<parameter name="Context">
<para>The context in the dialplan that Channel2 starts in.</para>
</parameter>
<parameter name="Exten">
<para>The extension in the dialplan that Channel2 starts in.</para>
</parameter>
<parameter name="LocalOptimization">
<enumlist>
<enum name="Yes"/>
<enum name="No"/>
</enumlist>
</parameter>
</syntax>
</managerEventInstance>
***/
manager_event(EVENT_FLAG_CALL, "LocalBridge",
"Channel1: %s\r\n"
"Channel2: %s\r\n"
"Uniqueid1: %s\r\n"
"Uniqueid2: %s\r\n"
"Context: %s\r\n"
"Exten: %s\r\n"
"LocalOptimization: %s\r\n",
ast_channel_name(p->owner), ast_channel_name(p->chan), ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
p->context, p->exten,
ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "Yes" : "No");
/* Start switch on sub channel */
if (!(res = ast_pbx_start(chan))) {
ao2_lock(p);
ast_set_flag(p, LOCAL_LAUNCHED_PBX);
ao2_unlock(p);
}
chan = ast_channel_unref(chan); /* chan is already unlocked, clear it here so the cleanup lable won't touch it. */
return_cleanup:
if (p) {
if (pvt_locked) {
ao2_unlock(p);
}
ao2_ref(p, -1);
}
if (chan) {
ast_channel_unlock(chan);
chan = ast_channel_unref(chan);
}
/* owner is supposed to be == to ast, if it
* is, don't unlock it because ast must exit locked */
if (owner) {
if (owner != ast) {
ast_channel_unlock(owner);
ast_channel_lock(ast);
}
owner = ast_channel_unref(owner);
} else {
/* we have to exit with ast locked */
ast_channel_lock(ast);
}
return res;
}
/*! \brief Hangup a call through the local proxy channel */
static int local_hangup(struct ast_channel *ast)
{
struct local_pvt *p = ast_channel_tech_pvt(ast);
int isoutbound;
int hangup_chan = 0;
int res = 0;
struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = ast_channel_hangupcause(ast) };
struct ast_channel *owner = NULL;
struct ast_channel *chan = NULL;
if (!p) {
return -1;
}
/* give the pvt a ref since we are unlocking the channel. */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, 1);
/* the pvt isn't going anywhere, we gave it a ref */
ast_channel_unlock(ast);
/* lock everything */
awesome_locking(p, &chan, &owner);
if (ast != chan && ast != owner) {
res = -1;
goto local_hangup_cleanup;
}
isoutbound = IS_OUTBOUND(ast, p); /* just comparing pointer of ast */
if (p->chan && ast_channel_hangupcause(ast) == AST_CAUSE_ANSWERED_ELSEWHERE) {
ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
ast_debug(2, "This local call has AST_CAUSE_ANSWERED_ELSEWHERE set.\n");
}
if (isoutbound) {
const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
if ((status) && (p->owner)) {
ast_channel_hangupcause_set(p->owner, ast_channel_hangupcause(p->chan));
pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
ast_module_user_remove(p->u_chan);
p->chan = NULL;
} else {
ast_module_user_remove(p->u_owner);
if (p->chan) {
ast_queue_hangup(p->chan);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
p->owner = NULL;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ast_channel_tech_pvt_set(ast, NULL); /* this is one of our locked channels, doesn't matter which */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
if (!p->owner && !p->chan) {
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
/* Remove from list */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlink(locals, p);
ao2_ref(p, -1);
p = NULL;
res = 0;
goto local_hangup_cleanup;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX)) {
/* Need to actually hangup since there is no PBX */
hangup_chan = 1;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
} else {
local_queue_frame(p, isoutbound, &f, NULL, 0);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
local_hangup_cleanup:
if (p) {
ao2_unlock(p);
ao2_ref(p, -1);
}
if (chan) {
ast_channel_unlock(chan);
if (hangup_chan) {
ast_hangup(chan);
}
chan = ast_channel_unref(chan);
}
if (owner) {
ast_channel_unlock(owner);
owner = ast_channel_unref(owner);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
/* leave with the same stupid channel locked that came in */
ast_channel_lock(ast);
return res;
}
static void local_destroy(void *obj)
{
struct local_pvt *pvt = obj;
pvt->reqcap = ast_format_cap_destroy(pvt->reqcap);
}
/*! \brief Create a call structure */
static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
{
struct local_pvt *tmp = NULL;
char *c = NULL, *opts = NULL;
if (!(tmp = ao2_alloc(sizeof(*tmp), local_destroy))) {
return NULL;
}
if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
ao2_ref(tmp, -1);
return NULL;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
}
/* Initialize private structure information */
ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
/* Look for options */
if ((opts = strchr(tmp->exten, '/'))) {
*opts++ = '\0';
if (strchr(opts, 'n'))
ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
if (strchr(opts, 'j')) {
if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
else {
ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
"to use the 'j' option to enable the jitterbuffer\n");
}
}
if (strchr(opts, 'b')) {
ast_set_flag(tmp, LOCAL_BRIDGE);
}
if (strchr(opts, 'm')) {
ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
}
}
/* Look for a context */
if ((c = strchr(tmp->exten, '@')))
*c++ = '\0';
ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
#if 0
/* We can't do this check here, because we don't know the CallerID yet, and
* the CallerID could potentially affect what step is actually taken (or
* even if that step exists). */
if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
tmp = local_pvt_destroy(tmp);
} else {
#endif
/* Add to list */
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_link(locals, tmp);
#if 0
}
#endif
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
return tmp; /* this is returned with a ref */
}
/*! \brief Start new local channel */
static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid, struct ast_callid *callid)
{
struct ast_channel *tmp = NULL, *tmp2 = NULL;
int randnum = ast_random() & 0xffff;
struct ast_format fmt;
const char *t;
int ama;
/* Allocate two new Asterisk channels */
/* safe accountcode */
if (p->owner && ast_channel_accountcode(p->owner))
t = ast_channel_accountcode(p->owner);
else
t = "";
if (p->owner)
ama = ast_channel_amaflags(p->owner);
else
ama = 0;
Multiple revisions 365006,365068 ........ r365006 | twilson | 2012-05-02 10:49:03 -0500 (Wed, 02 May 2012) | 12 lines Fix a CEL LINKEDID_END race and local channel linkedids This patch has the ;2 channel inherit the linkedid of the ;1 channel and fixes the race condition by no longer scanning the channel list for "other" channels with the same linkedid. Instead, cel.c has an ao2 container of linkedid strings and uses the refcount of the string as a counter of how many channels with the linkedid exist. Not only does this eliminate the race condition, but it also allows us to look up the linkedid by the hashed key instead of traversing the entire channel list. Review: https://reviewboard.asterisk.org/r/1895/ ........ r365068 | twilson | 2012-05-02 12:02:39 -0500 (Wed, 02 May 2012) | 11 lines Don't leak a ref if out of memory and can't link the linkedid If the ao2_link fails, we are most likely out of memory and bad things are going to happen. Before those bad things happen, make sure to clean up the linkedid references. This patch also adds a comment explaining why linkedid can't be passed to both local channel allocations and combines two ao2_ref calls into 1. Review: https://reviewboard.asterisk.org/r/1895/ ........ Merged revisions 365006,365068 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 365083 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@365084 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-05-02 17:43:16 +00:00
/* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
* allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
|| !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, ast_channel_linkedid(tmp), ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
Convert the ast_channel data structure over to the astobj2 framework. There is a lot that could be said about this, but the patch is a big improvement for performance, stability, code maintainability, and ease of future code development. The channel list is no longer an unsorted linked list. The main container for channels is an astobj2 hash table. All of the code related to searching for channels or iterating active channels has been rewritten. Let n be the number of active channels. Iterating the channel list has gone from O(n^2) to O(n). Searching for a channel by name went from O(n) to O(1). Searching for a channel by extension is still O(n), but uses a new method for doing so, which is more efficient. The ast_channel object is now a reference counted object. The benefits here are plentiful. Some benefits directly related to issues in the previous code include: 1) When threads other than the channel thread owning a channel wanted access to a channel, it had to hold the lock on it to ensure that it didn't go away. This is no longer a requirement. Holding a reference is sufficient. 2) There are places that now require less dealing with channel locks. 3) There are places where channel locks are held for much shorter periods of time. 4) There are places where dealing with more than one channel at a time becomes _MUCH_ easier. ChanSpy is a great example of this. Writing code in the future that deals with multiple channels will be much easier. Some additional information regarding channel locking and reference count handling can be found in channel.h, where a new section has been added that discusses some of the rules associated with it. Mark Michelson also assisted with the development of this patch. He did the conversion of ChanSpy and introduced a new API, ast_autochan, which makes it much easier to deal with holding on to a channel pointer for an extended period of time and having it get automatically updated if the channel gets masqueraded. Mark was also a huge help in the code review process. Thanks to David Vossel for his assistance with this branch, as well. David did the conversion of the DAHDIScan application by making it become a wrapper for ChanSpy internally. The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch. Review: http://reviewboard.digium.com/r/203/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2009-04-24 14:04:26 +00:00
if (tmp) {
tmp = ast_channel_release(tmp);
}
ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
return NULL;
Convert the ast_channel data structure over to the astobj2 framework. There is a lot that could be said about this, but the patch is a big improvement for performance, stability, code maintainability, and ease of future code development. The channel list is no longer an unsorted linked list. The main container for channels is an astobj2 hash table. All of the code related to searching for channels or iterating active channels has been rewritten. Let n be the number of active channels. Iterating the channel list has gone from O(n^2) to O(n). Searching for a channel by name went from O(n) to O(1). Searching for a channel by extension is still O(n), but uses a new method for doing so, which is more efficient. The ast_channel object is now a reference counted object. The benefits here are plentiful. Some benefits directly related to issues in the previous code include: 1) When threads other than the channel thread owning a channel wanted access to a channel, it had to hold the lock on it to ensure that it didn't go away. This is no longer a requirement. Holding a reference is sufficient. 2) There are places that now require less dealing with channel locks. 3) There are places where channel locks are held for much shorter periods of time. 4) There are places where dealing with more than one channel at a time becomes _MUCH_ easier. ChanSpy is a great example of this. Writing code in the future that deals with multiple channels will be much easier. Some additional information regarding channel locking and reference count handling can be found in channel.h, where a new section has been added that discusses some of the rules associated with it. Mark Michelson also assisted with the development of this patch. He did the conversion of ChanSpy and introduced a new API, ast_autochan, which makes it much easier to deal with holding on to a channel pointer for an extended period of time and having it get automatically updated if the channel gets masqueraded. Mark was also a huge help in the code review process. Thanks to David Vossel for his assistance with this branch, as well. David did the conversion of the DAHDIScan application by making it become a wrapper for ChanSpy internally. The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch. Review: http://reviewboard.digium.com/r/203/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2009-04-24 14:04:26 +00:00
}
if (callid) {
ast_channel_callid_set(tmp, callid);
ast_channel_callid_set(tmp2, callid);
}
ast_channel_tech_set(tmp, &local_tech);
ast_channel_tech_set(tmp2, &local_tech);
ast_format_cap_copy(ast_channel_nativeformats(tmp), p->reqcap);
ast_format_cap_copy(ast_channel_nativeformats(tmp2), p->reqcap);
/* Determine our read/write format and set it on each channel */
ast_best_codec(p->reqcap, &fmt);
ast_format_copy(ast_channel_writeformat(tmp), &fmt);
ast_format_copy(ast_channel_writeformat(tmp2), &fmt);
ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
ast_format_copy(ast_channel_rawwriteformat(tmp2), &fmt);
ast_format_copy(ast_channel_readformat(tmp), &fmt);
ast_format_copy(ast_channel_readformat(tmp2), &fmt);
ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
ast_format_copy(ast_channel_rawreadformat(tmp2), &fmt);
ast_channel_tech_pvt_set(tmp, p);
ast_channel_tech_pvt_set(tmp2, p);
p->owner = tmp;
p->chan = tmp2;
p->u_owner = ast_module_user_add(p->owner);
p->u_chan = ast_module_user_add(p->chan);
ast_channel_context_set(tmp, p->context);
ast_channel_context_set(tmp2, p->context);
ast_channel_exten_set(tmp2, p->exten);
ast_channel_priority_set(tmp, 1);
ast_channel_priority_set(tmp2, 1);
ast_jb_configure(tmp, &p->jb_conf);
return tmp;
}
/*! \brief Part of PBX interface */
static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
{
struct local_pvt *p;
struct ast_channel *chan;
struct ast_callid *callid = ast_read_threadstorage_callid();
/* Allocate a new private structure and then Asterisk channel */
p = local_alloc(data, cap);
if (!p) {
chan = NULL;
goto local_request_end;
}
chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, callid);
if (!chan) {
ao2_unlink(locals, p);
} else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
ao2_unlink(locals, p);
p->owner = ast_channel_release(p->owner);
ast_module_user_remove(p->u_owner);
p->chan = ast_channel_release(p->chan);
ast_module_user_remove(p->u_chan);
chan = NULL;
}
ao2_ref(p, -1); /* kill the ref from the alloc */
local_request_end:
if (callid) {
ast_callid_unref(callid);
}
return chan;
}
/*! \brief CLI command "local show channels" */
static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
struct local_pvt *p = NULL;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
struct ao2_iterator it;
switch (cmd) {
case CLI_INIT:
e->command = "local show channels";
e->usage =
"Usage: local show channels\n"
" Provides summary information on active local proxy channels.\n";
return NULL;
case CLI_GENERATE:
return NULL;
}
if (a->argc != 3) {
return CLI_SHOWUSAGE;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
if (ao2_container_count(locals) == 0) {
ast_cli(a->fd, "No local channels in use\n");
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
return RESULT_SUCCESS;
}
it = ao2_iterator_init(locals, 0);
while ((p = ao2_iterator_next(&it))) {
ao2_lock(p);
Replace direct access to channel name with accessor functions There are many benefits to making the ast_channel an opaque handle, from increasing maintainability to presenting ways to kill masquerades. This patch kicks things off by taking things a field at a time, renaming the field to '__do_not_use_${fieldname}' and then writing setters/getters and converting the existing code to using them. When all fields are done, we can move ast_channel to a C file from channel.h and lop off the '__do_not_use_'. This patch sets up main/channel_interal_api.c to be the only file that actually accesses the ast_channel's fields directly. The intent would be for any API functions in channel.c to use the accessor functions. No more monkeying around with channel internals. We should use our own APIs. The interesting changes in this patch are the addition of channel_internal_api.c, the moving of the AST_DATA stuff from channel.c to channel_internal_api.c (note: the AST_DATA stuff will have to be reworked to use accessor functions when ast_channel is really opaque), and some re-working of the way channel iterators/callbacks are handled so as to avoid creating fake ast_channels on the stack to pass in matching data by directly accessing fields (since "name" is a stringfield and the fake channel doesn't init the stringfields, you can't use the ast_channel_name_set() function). I went with ast_channel_name(chan) for a getter, and ast_channel_name_set(chan, name) for a setter. The majority of the grunt-work for this change was done by writing a semantic patch using Coccinelle ( http://coccinelle.lip6.fr/ ). Review: https://reviewboard.asterisk.org/r/1655/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@350223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2012-01-09 22:15:50 +00:00
ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? ast_channel_name(p->owner) : "<unowned>", p->exten, p->context);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(p);
ao2_ref(p, -1);
}
ao2_iterator_destroy(&it);
return CLI_SUCCESS;
}
static struct ast_cli_entry cli_local[] = {
AST_CLI_DEFINE(locals_show, "List status of local channels"),
};
static int manager_optimize_away(struct mansession *s, const struct message *m)
{
const char *channel;
struct local_pvt *p, *tmp = NULL;
struct ast_channel *c;
int found = 0;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
struct ao2_iterator it;
channel = astman_get_header(m, "Channel");
if (ast_strlen_zero(channel)) {
astman_send_error(s, m, "'Channel' not specified.");
return 0;
}
c = ast_channel_get_by_name(channel);
if (!c) {
astman_send_error(s, m, "Channel does not exist.");
return 0;
}
p = ast_channel_tech_pvt(c);
ast_channel_unref(c);
c = NULL;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
it = ao2_iterator_init(locals, 0);
while ((tmp = ao2_iterator_next(&it))) {
if (tmp == p) {
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_lock(tmp);
found = 1;
ast_clear_flag(tmp, LOCAL_NO_OPTIMIZATION);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_unlock(tmp);
ao2_ref(tmp, -1);
break;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(tmp, -1);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_iterator_destroy(&it);
if (found) {
astman_send_ack(s, m, "Queued channel to be optimized away");
} else {
astman_send_error(s, m, "Unable to find channel");
}
return 0;
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
static int locals_cmp_cb(void *obj, void *arg, int flags)
{
return (obj == arg) ? CMP_MATCH : 0;
}
/*! \brief Load module into PBX, register channel */
static int load_module(void)
{
if (!(local_tech.capabilities = ast_format_cap_alloc())) {
return AST_MODULE_LOAD_FAILURE;
}
ast_format_cap_add_all(local_tech.capabilities);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
ast_format_cap_destroy(local_tech.capabilities);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
return AST_MODULE_LOAD_FAILURE;
}
/* Make sure we can register our channel type */
if (ast_channel_register(&local_tech)) {
ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(locals, -1);
ast_format_cap_destroy(local_tech.capabilities);
return AST_MODULE_LOAD_FAILURE;
}
ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
ast_manager_register_xml("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
return AST_MODULE_LOAD_SUCCESS;
}
/*! \brief Unload the local proxy channel from Asterisk */
static int unload_module(void)
{
struct local_pvt *p = NULL;
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
struct ao2_iterator it;
/* First, take us out of the channel loop */
ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
ast_manager_unregister("LocalOptimizeAway");
ast_channel_unregister(&local_tech);
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
it = ao2_iterator_init(locals, 0);
while ((p = ao2_iterator_next(&it))) {
if (p->owner) {
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
}
Merged revisions 292868 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r292868 | dvossel | 2010-10-25 14:07:50 -0500 (Mon, 25 Oct 2010) | 39 lines Merged revisions 292867 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ................ r292867 | dvossel | 2010-10-25 14:06:21 -0500 (Mon, 25 Oct 2010) | 32 lines Merged revisions 292866 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r292866 | dvossel | 2010-10-25 14:05:07 -0500 (Mon, 25 Oct 2010) | 27 lines This patch turns chan_local pvts into astobj2 objects. chan_local does some dangerous things involving deadlock avoidance. tech_pvt functions like hangup and queue_frame are provided with a locked channel upon entry. Those functions are completely safe as long as you don't attempt to give up that channel lock, but that is impossible to guarantee due to the required deadlock avoidance necessary to lock both the tech_pvt and both channels involved. In the past, we have tried to account for this by doing things like setting a "glare" flag that indicates what function should destroy the pvt. This was used in local_hangup and local_queue_frame to decided who should destroy the pvt if they collided in separate threads. I have removed the need to do this by converting all chan_local tech_pvts to astobj2. This means we can ref a pvt before deadlock avoidance and not have to worry about that pvt possibly getting destroyed under us. It also cleans up where we destroy the tech_pvt. The only unlink from the tech_pvt container occurs in local_hangup now, which is where it should occur. Since there still may be thread collisions on some functions like local_hangup after deadlock avoidance, I have added some checks to detect those collisions and exit appropriately. I think this patch is going to solve quite a bit of weirdness we have had with local channels in the past. ........ ................ ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@292869 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-10-25 19:11:42 +00:00
ao2_ref(p, -1);
}
ao2_iterator_destroy(&it);
ao2_ref(locals, -1);
ast_format_cap_destroy(local_tech.capabilities);
return 0;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Local Proxy Channel (Note: used internally by other modules)",
.load = load_module,
.unload = unload_module,
.load_pri = AST_MODPRI_CHANNEL_DRIVER,
);