From: Frederic LE FOLL Date: Thu, 30 Aug 2018 08:42:18 +0000 (+0200) Subject: res_musiconhold.c: Restart MOH if previous hold just reached end-of-file X-Git-Tag: 15.7.0-rc1~51^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d22c4d19998f90c1ff517b7195676b3ef620aae2;p=thirdparty%2Fasterisk.git res_musiconhold.c: Restart MOH if previous hold just reached end-of-file On MOH activation, moh_files_readframe() is called while the current stream attached to the channel is NULL and it calls ast_moh_files_next() immediately. However, it won't call ast_moh_files_next() again if sample reading fails. The failure may occur because res_musiconhold retains the last sample reading position in the channel data and MOH during the previous hold/retrieve just reached EOF. Obviously, a bit of bad luck is required here. * Restructured moh_files_readframe() to try a second time to start MOH if there was no stream setup and the saved position was at EOF. Also added comments describing what is going on for each step. ASTERISK-28029 Change-Id: I1508cf2c094f8feca22d6f76deaa9fdfa9944860 --- diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 137f83bac7..5c739ab8fd 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -402,11 +402,28 @@ static int ast_moh_files_next(struct ast_channel *chan) static struct ast_frame *moh_files_readframe(struct ast_channel *chan) { - struct ast_frame *f = NULL; - - if (!(ast_channel_stream(chan) && (f = ast_readframe(ast_channel_stream(chan))))) { - if (!ast_moh_files_next(chan)) + struct ast_frame *f; + + f = ast_readframe(ast_channel_stream(chan)); + if (!f) { + /* Either there was no file stream setup or we reached EOF. */ + if (!ast_moh_files_next(chan)) { + /* + * Either we resetup the previously saved file stream position + * or we started a new file stream. + */ f = ast_readframe(ast_channel_stream(chan)); + if (!f) { + /* + * We can get here if we were very unlucky because the + * resetup file stream was saved at EOF when MOH was + * previously stopped. + */ + if (!ast_moh_files_next(chan)) { + f = ast_readframe(ast_channel_stream(chan)); + } + } + } } return f;