aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-01-08 19:44:28 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-01-08 19:44:28 +0000
commitfb382636e1b402298d10c58026f6fd1fd1660b3d (patch)
tree01c7266a13af9ddfc7ee4fcae0acf9b11a457f3c
parentbf4245fa15907c03e4426a4354afc17e4be04120 (diff)
Merged revisions 238635 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r238635 | dvossel | 2010-01-08 13:39:30 -0600 (Fri, 08 Jan 2010) | 22 lines fixes AUDIOHOOK_INHERIT regression During the process of removing an audiohook from one channel and attaching it to another the audiohook's status is updated to DONE and then back to whatever it was previously. Typically updating the status after setting it to DONE is not a good idea because DONE can trigger unrecoverable audiohook destruction events... because of this a conditional check was added to audiohook_update_status to explicitly prevent the audiohook from ever changing after being set to DONE. It was this check that prevented audiohook inherit from work properly though. Now ast_audiohook_move_by_source is treated as a special exception, as the audiohook must be returned to its previous status after attaching it to the new channel. This is only a safe operation because the audiohook's lock is held the entire time, otherwise this could cause trouble. (closes issue #16522) Reported by: corruptor ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@238638 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--include/asterisk/audiohook.h3
-rw-r--r--main/audiohook.c11
2 files changed, 13 insertions, 1 deletions
diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
index 6de97a69b..5fb863ac0 100644
--- a/include/asterisk/audiohook.h
+++ b/include/asterisk/audiohook.h
@@ -205,6 +205,9 @@ struct ast_frame *ast_audiohook_write_list(struct ast_channel *chan, struct ast_
/*! \brief Update audiohook's status
* \param audiohook Audiohook structure
* \param audiohook status enum
+ *
+ * \note once status is updated to DONE, this function can not be used to set the
+ * status back to any other setting. Setting DONE effectively locks the status as such.
*/
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status);
diff --git a/main/audiohook.c b/main/audiohook.c
index 5d4feeaaf..b0fb48ad6 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -361,7 +361,11 @@ int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audioho
/*! \brief Update audiohook's status
* \param audiohook status enum
* \param audiohook Audiohook structure
+ *
+ * \note once status is updated to DONE, this function can not be used to set the
+ * status back to any other setting. Setting DONE effectively locks the status as such.
*/
+
void ast_audiohook_update_status(struct ast_audiohook *audiohook, enum ast_audiohook_status status)
{
ast_audiohook_lock(audiohook);
@@ -458,6 +462,7 @@ static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list
void ast_audiohook_move_by_source(struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source)
{
struct ast_audiohook *audiohook;
+ enum ast_audiohook_status oldstatus;
if (!old_chan->audiohooks || !(audiohook = find_audiohook_by_source(old_chan->audiohooks, source))) {
return;
@@ -466,11 +471,15 @@ void ast_audiohook_move_by_source(struct ast_channel *old_chan, struct ast_chann
/* By locking both channels and the audiohook, we can assure that
* another thread will not have a chance to read the audiohook's status
* as done, even though ast_audiohook_remove signals the trigger
- * condition
+ * condition.
*/
ast_audiohook_lock(audiohook);
+ oldstatus = audiohook->status;
+
ast_audiohook_remove(old_chan, audiohook);
ast_audiohook_attach(new_chan, audiohook);
+
+ audiohook->status = oldstatus;
ast_audiohook_unlock(audiohook);
}