aboutsummaryrefslogtreecommitdiffstats
path: root/res
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 17:37:50 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 17:37:50 +0000
commit6e91593b539b4f469850be5a2b75eca6b77817b7 (patch)
tree6c46f6fe7fed454d61e668e39583efc0fbe4cae6 /res
parentcd9ace1c17be6567784b3bcb038eddd6c797be94 (diff)
Merged revisions 187421,187424 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r187421 | mmichelson | 2009-04-09 12:30:39 -0500 (Thu, 09 Apr 2009) | 21 lines Fix a crash in res_musiconhold when using cached realtime moh. The moh_register function links an mohclass and then immediately unrefs the class since the container now has a reference. The problem with using realtime music on hold is that the class is allocated, registered, and started in one fell swoop. The refcounting logic resulted in the count being off by one. The same problem did not happen when using a static config because the allocation and registration of an mohclass is a separate operation from starting moh. This also did not affect non-cached realtime moh because the classes are not registered at all. I also have modified res_musiconhold to use the _t_ variants of the ao2_ functions so that more info can be gleaned when attempting to trace the refcounts. I found this to be incredibly helpful for debugging this issue and there's no good reason to remove it. (closes issue #14661) Reported by: sum ........ r187424 | mmichelson | 2009-04-09 12:34:39 -0500 (Thu, 09 Apr 2009) | 3 lines Use safe macro practices even though they really aren't necessary. ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@187425 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res')
-rw-r--r--res/res_musiconhold.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index a05279130..d64c5d8c0 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -1082,7 +1082,7 @@ static int init_app_class(struct mohclass *class)
/*!
* \note This function owns the reference it gets to moh
*/
-static int moh_register(struct mohclass *moh, int reload)
+static int moh_register(struct mohclass *moh, int reload, int unref)
{
struct mohclass *mohclass = NULL;
@@ -1119,7 +1119,9 @@ static int moh_register(struct mohclass *moh, int reload)
ao2_link(mohclasses, moh);
- moh = mohclass_unref(moh);
+ if (unref) {
+ moh = mohclass_unref(moh);
+ }
return 0;
}
@@ -1246,7 +1248,13 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
mohclass = state->class;
}
}
- moh_register(mohclass, 0);
+ /* We don't want moh_register to unref the mohclass because we do it at the end of this function as well.
+ * If we allowed moh_register to unref the mohclass,too, then the count would be off by one. The result would
+ * be that the destructor would be called when the generator on the channel is deactivated. The container then
+ * has a pointer to a freed mohclass, so any operations involving the mohclass container would result in reading
+ * invalid memory.
+ */
+ moh_register(mohclass, 0, 0);
} else {
/* We don't register RT moh class, so let's init it manualy */
@@ -1510,7 +1518,7 @@ static int load_moh_classes(int reload)
}
/* Don't leak a class when it's already registered */
- if (!moh_register(class, reload)) {
+ if (!moh_register(class, reload, 1)) {
numclasses++;
}
}