mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-13 16:21:01 +00:00
chan_local: Misc lock and ref tweaks.
* awesome_locking() does not need to thrash the pvt lock as much. * local_setoption() does not need to check for NULL pvt on cleanup since it will never be NULL. * Made ref the pvt before locking for consistency. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@378072 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -161,7 +161,7 @@ struct local_pvt {
|
|||||||
#define LOCAL_BRIDGE (1 << 3) /*!< Report back the "true" channel as being bridged to */
|
#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 */
|
#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
|
* \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 NO locks should be held prior to calling this function
|
||||||
@@ -175,8 +175,8 @@ static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, s
|
|||||||
struct ast_channel *chan = NULL;
|
struct ast_channel *chan = NULL;
|
||||||
struct ast_channel *owner = NULL;
|
struct ast_channel *owner = NULL;
|
||||||
|
|
||||||
|
ao2_lock(p);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ao2_lock(p);
|
|
||||||
if (p->chan) {
|
if (p->chan) {
|
||||||
chan = p->chan;
|
chan = p->chan;
|
||||||
ast_channel_ref(chan);
|
ast_channel_ref(chan);
|
||||||
@@ -194,12 +194,11 @@ static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, s
|
|||||||
} else if(chan) {
|
} else if(chan) {
|
||||||
ast_channel_lock(chan);
|
ast_channel_lock(chan);
|
||||||
}
|
}
|
||||||
ao2_lock(p);
|
|
||||||
} else {
|
} else {
|
||||||
/* lock both channels first, then get the pvt lock */
|
/* lock both channels first, then get the pvt lock */
|
||||||
ast_channel_lock_both(chan, owner);
|
ast_channel_lock_both(chan, owner);
|
||||||
ao2_lock(p);
|
|
||||||
}
|
}
|
||||||
|
ao2_lock(p);
|
||||||
|
|
||||||
/* Now that we have all the locks, validate that nothing changed */
|
/* Now that we have all the locks, validate that nothing changed */
|
||||||
if (p->owner != owner || p->chan != chan) {
|
if (p->owner != owner || p->chan != chan) {
|
||||||
@@ -211,7 +210,6 @@ static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, s
|
|||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
chan = ast_channel_unref(chan);
|
chan = ast_channel_unref(chan);
|
||||||
}
|
}
|
||||||
ao2_unlock(p);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,7 +223,7 @@ static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, s
|
|||||||
static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
|
static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
struct local_pvt *p = NULL;
|
struct local_pvt *p;
|
||||||
struct ast_channel *otherchan = NULL;
|
struct ast_channel *otherchan = NULL;
|
||||||
ast_chan_write_info_t *write_info;
|
ast_chan_write_info_t *write_info;
|
||||||
|
|
||||||
@@ -272,9 +270,7 @@ static int local_setoption(struct ast_channel *ast, int option, void * data, int
|
|||||||
ast_channel_unlock(otherchan);
|
ast_channel_unlock(otherchan);
|
||||||
|
|
||||||
setoption_cleanup:
|
setoption_cleanup:
|
||||||
if (p) {
|
ao2_ref(p, -1);
|
||||||
ao2_ref(p, -1);
|
|
||||||
}
|
|
||||||
if (otherchan) {
|
if (otherchan) {
|
||||||
ast_channel_unref(otherchan);
|
ast_channel_unref(otherchan);
|
||||||
}
|
}
|
||||||
@@ -468,8 +464,8 @@ static int local_answer(struct ast_channel *ast)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ao2_lock(p);
|
|
||||||
ao2_ref(p, 1);
|
ao2_ref(p, 1);
|
||||||
|
ao2_lock(p);
|
||||||
isoutbound = IS_OUTBOUND(ast, p);
|
isoutbound = IS_OUTBOUND(ast, p);
|
||||||
if (isoutbound) {
|
if (isoutbound) {
|
||||||
/* Pass along answer since somebody answered us */
|
/* Pass along answer since somebody answered us */
|
||||||
@@ -839,8 +835,8 @@ static int local_sendtext(struct ast_channel *ast, const char *text)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ao2_lock(p);
|
|
||||||
ao2_ref(p, 1); /* ref for local_queue_frame */
|
ao2_ref(p, 1); /* ref for local_queue_frame */
|
||||||
|
ao2_lock(p);
|
||||||
isoutbound = IS_OUTBOUND(ast, p);
|
isoutbound = IS_OUTBOUND(ast, p);
|
||||||
f.data.ptr = (char *) text;
|
f.data.ptr = (char *) text;
|
||||||
f.datalen = strlen(text) + 1;
|
f.datalen = strlen(text) + 1;
|
||||||
@@ -861,8 +857,8 @@ static int local_sendhtml(struct ast_channel *ast, int subclass, const char *dat
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ao2_lock(p);
|
|
||||||
ao2_ref(p, 1); /* ref for local_queue_frame */
|
ao2_ref(p, 1); /* ref for local_queue_frame */
|
||||||
|
ao2_lock(p);
|
||||||
isoutbound = IS_OUTBOUND(ast, p);
|
isoutbound = IS_OUTBOUND(ast, p);
|
||||||
f.subclass.integer = subclass;
|
f.subclass.integer = subclass;
|
||||||
f.data.ptr = (char *)data;
|
f.data.ptr = (char *)data;
|
||||||
|
Reference in New Issue
Block a user