aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlmadsen <lmadsen@f38db490-d61c-443f-a65b-d21fe96a405b>2010-05-03 15:26:26 +0000
committerlmadsen <lmadsen@f38db490-d61c-443f-a65b-d21fe96a405b>2010-05-03 15:26:26 +0000
commit0693d1112836b1669315f79d401504d8010f71bf (patch)
tree9d72e1fd9f11395d6ce56f551088f7306c368b41
parent8b9e322bdd93639972bb1ecb55bf367712e41ec3 (diff)
parent8c3949644a1136037f43ff55d85cc4c4c98c50d0 (diff)
Create Asterisk 1.6.1.19 release from 1.6.1.19-rc3.
git-svn-id: http://svn.digium.com/svn/asterisk/tags/1.6.1.19@260614 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--.version2
-rw-r--r--ChangeLog20
-rw-r--r--channels/chan_local.c19
-rw-r--r--include/asterisk/audiohook.h13
-rw-r--r--main/audiohook.c45
-rw-r--r--main/channel.c7
6 files changed, 81 insertions, 25 deletions
diff --git a/.version b/.version
index 8bc156caa..8a9125317 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-1.6.1.19-rc2
+1.6.1.19-rc3
diff --git a/ChangeLog b/ChangeLog
index ab3cc6ba3..3b4962113 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2010-04-29 Leif Madsen <lmadsen@digium.com>
+
+ * Asterisk 1.6.1.19-rc3 Released
+
+2010-04-29 10:31 +0000 [r260052] David Vossel <dvossel@digium.com>
+
+ * include/asterisk/audiohook.h, main/audiohook.c: Fixes crash in
+ audiohook_write_list. (closes issue 0017052) Reported by: dvossel
+ Tested by: dvossel. (closes issue 0016196) Reported by: atis.
+ Review: https://reviewboard.asterisk.org/r/623/
+
+2010-04-28 10:31 +0000 [r259930] David Vossel <dvossel@digium.com>
+
+ * channels/chan_local.c, main/channel.c: Resolves deadlocks in
+ chan_local. (closes issue 0017185) Reported by: schmoozecom
+ Patches: issue_17185_v1.diff uploaded by dvossel (license 671)
+ issue_17185_v2.diff uploaded by dvossel (license 671) Tested
+ by: schmoozecom, GameGamer43
+ Review: https://reviewboard.asterisk.org/r/631/
+
2010-04-13 Leif Madsen <lmadsen@digium.com>
* Asterisk 1.6.1.19-rc2 Released
diff --git a/channels/chan_local.c b/channels/chan_local.c
index 7ed607d2c..2cd02c961 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -580,12 +580,12 @@ static int local_hangup(struct ast_channel *ast)
/* Deadlock avoidance */
while (p->owner && ast_channel_trylock(p->owner)) {
ast_mutex_unlock(&p->lock);
- if (ast) {
- ast_channel_unlock(ast);
+ if (p->chan) {
+ ast_channel_unlock(p->chan);
}
usleep(1);
- if (ast) {
- ast_channel_lock(ast);
+ if (p->chan) {
+ ast_channel_lock(p->chan);
}
ast_mutex_lock(&p->lock);
}
@@ -600,8 +600,17 @@ static int local_hangup(struct ast_channel *ast)
} else {
ast_module_user_remove(p->u_owner);
while (p->chan && ast_channel_trylock(p->chan)) {
- DEADLOCK_AVOIDANCE(&p->lock);
+ ast_mutex_unlock(&p->lock);
+ if (p->owner) {
+ ast_channel_unlock(p->owner);
+ }
+ usleep(1);
+ if (p->owner) {
+ ast_channel_lock(p->owner);
+ }
+ ast_mutex_lock(&p->lock);
}
+
p->owner = NULL;
if (p->chan) {
ast_queue_hangup(p->chan);
diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
index 5fb863ac0..a42d48fef 100644
--- a/include/asterisk/audiohook.h
+++ b/include/asterisk/audiohook.h
@@ -73,9 +73,16 @@ struct ast_audiohook;
* \param chan Channel
* \param frame Frame of audio to manipulate
* \param direction Direction frame came from
- * \return Returns 0 on success, -1 on failure
- * \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
- * via it's own method. An example would be datastores.
+ * \return Returns 0 on success, -1 on failure.
+ * \note An audiohook does not have any reference to a private data structure for manipulate
+ * types. It is up to the manipulate callback to store this data via it's own method.
+ * An example would be datastores.
+ * \note The input frame should never be freed or corrupted during a manipulate callback.
+ * If the callback has the potential to corrupt the frame's data during manipulation,
+ * local data should be used for the manipulation and only copied to the frame on
+ * success.
+ * \note A failure return value indicates that the frame was not manipulated and that
+ * is being returned in its original state.
*/
typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
diff --git a/main/audiohook.c b/main/audiohook.c
index b0fb48ad6..2dd2bea35 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -572,7 +572,29 @@ static struct ast_frame *dtmf_audiohook_write_list(struct ast_channel *chan, str
return frame;
}
-/*! \brief Pass an AUDIO frame off to be handled by the audiohook core
+/*!
+ * \brief Pass an AUDIO frame off to be handled by the audiohook core
+ *
+ * \details
+ * This function has 3 ast_frames and 3 parts to handle each. At the beginning of this
+ * function all 3 frames, start_frame, middle_frame, and end_frame point to the initial
+ * input frame.
+ *
+ * Part_1: Translate the start_frame into SLINEAR audio if it is not already in that
+ * format. The result of this part is middle_frame is guaranteed to be in
+ * SLINEAR format for Part_2.
+ * Part_2: Send middle_frame off to spies and manipulators. At this point middle_frame is
+ * either a new frame as result of the translation, or points directly to the start_frame
+ * because no translation to SLINEAR audio was required. The result of this part
+ * is end_frame will be updated to point to middle_frame if any audiohook manipulation
+ * took place.
+ * Part_3: Translate end_frame's audio back into the format of start frame if necessary.
+ * At this point if middle_frame != end_frame, we are guaranteed that no manipulation
+ * took place and middle_frame can be freed as it was translated... If middle_frame was
+ * not translated and still pointed to start_frame, it would be equal to end_frame as well
+ * regardless if manipulation took place which would not result in this free. The result
+ * of this part is end_frame is guaranteed to be the format of start_frame for the return.
+ *
* \param chan Channel that the list is coming off of
* \param audiohook_list List of audiohooks
* \param direction Direction frame is coming in from
@@ -587,6 +609,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
struct ast_audiohook *audiohook = NULL;
int samples = frame->samples;
+ /* ---Part_1. translate start_frame to SLINEAR if necessary. */
/* If the frame coming in is not signed linear we have to send it through the in_translate path */
if (frame->subclass != AST_FORMAT_SLINEAR) {
if (in_translate->format != frame->subclass) {
@@ -601,6 +624,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
samples = middle_frame->samples;
}
+ /* ---Part_2: Send middle_frame to spy and manipulator lists. middle_frame is guaranteed to be SLINEAR here.*/
/* Queue up signed linear frame to each spy */
AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
ast_audiohook_lock(audiohook);
@@ -654,20 +678,21 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
audiohook->manipulate_callback(audiohook, chan, NULL, direction);
continue;
}
- /* Feed in frame to manipulation */
+ /* Feed in frame to manipulation. */
if (audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
- ast_frfree(middle_frame);
- middle_frame = NULL;
+ /* XXX IGNORE FAILURE */
+
+ /* If the manipulation fails then the frame will be returned in its original state.
+ * Since there are potentially more manipulator callbacks in the list, no action should
+ * be taken here to exit early. */
}
ast_audiohook_unlock(audiohook);
}
AST_LIST_TRAVERSE_SAFE_END;
- if (middle_frame) {
- end_frame = middle_frame;
- }
+ end_frame = middle_frame;
}
- /* Now we figure out what to do with our end frame (whether to transcode or not) */
+ /* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
if (middle_frame == end_frame) {
/* Middle frame was modified and became the end frame... let's see if we need to transcode */
if (end_frame->subclass != start_frame->subclass) {
@@ -692,9 +717,7 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
}
} else {
/* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
- if (middle_frame) {
- ast_frfree(middle_frame);
- }
+ ast_frfree(middle_frame);
}
return end_frame;
diff --git a/main/channel.c b/main/channel.c
index c3e75baae..420435aac 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1976,25 +1976,22 @@ int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen,
int res = 0;
ast_channel_lock(chan);
-
if (chan->generatordata) {
if (chan->generator && chan->generator->release)
chan->generator->release(chan, chan->generatordata);
chan->generatordata = NULL;
}
-
- ast_prod(chan);
if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
res = -1;
}
-
if (!res) {
ast_settimeout(chan, 50, generator_force, chan);
chan->generator = gen;
}
-
ast_channel_unlock(chan);
+ ast_prod(chan);
+
return res;
}