<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/9211">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Kevin Harwell: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, but someone else must approve; Approved for Submit
Sean Bright: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">autoservice: Don't start channel autoservice if the thread is a user interface.<br><br>Executing dialplan functions from either AMI or ARI by getting a variable<br>could place the channel into autoservice. However, these user interface<br>threads do not handle the channel's media so we wind up with two threads<br>attempting to handle the media.<br><br>There can be one and only one thread handling a channel's media at a time.<br>Otherwise, we don't know which thread is going to handle the media frames.<br><br>ASTERISK-27625<br><br>Change-Id: If2dc94ce15ddabf923ed1e2a65ea0ef56e013e49<br>---<br>M include/asterisk/utils.h<br>M main/autoservice.c<br>M main/tcptls.c<br>M main/utils.c<br>4 files changed, 80 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h<br>index f8f761d..379ae83 100644<br>--- a/include/asterisk/utils.h<br>+++ b/include/asterisk/utils.h<br>@@ -1195,4 +1195,22 @@<br> int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,<br> const char *file, int lineno, const char *function);<br> <br>+/*!<br>+ * \brief Set the current thread's user interface status.<br>+ *<br>+ * \param is_user_interface Non-zero to mark the thread as a user interface.<br>+ *<br>+ * \return 0 if successfuly marked current thread.<br>+ * \return Non-zero if marking current thread failed.<br>+ */<br>+int ast_thread_user_interface_set(int is_user_interface);<br>+<br>+/*!<br>+ * \brief Indicates whether the current thread is a user interface<br>+ *<br>+ * \return True (non-zero) if thread is a user interface.<br>+ * \return False (zero) if thread is not a user interface.<br>+ */<br>+int ast_thread_is_user_interface(void);<br>+<br> #endif /* _ASTERISK_UTILS_H */<br>diff --git a/main/autoservice.c b/main/autoservice.c<br>index f353f0e..40e4045 100644<br>--- a/main/autoservice.c<br>+++ b/main/autoservice.c<br>@@ -195,6 +195,13 @@<br> int res = 0;<br> struct asent *as;<br> <br>+ if (ast_thread_is_user_interface()) {<br>+ /* User interface threads do not handle channel media. */<br>+ ast_debug(1, "Thread is a user interface, not putting channel %s into autoservice\n",<br>+ ast_channel_name(chan));<br>+ return 0;<br>+ }<br>+<br> AST_LIST_LOCK(&aslist);<br> AST_LIST_TRAVERSE(&aslist, as, list) {<br> if (as->chan == chan) {<br>@@ -256,6 +263,13 @@<br> struct ast_frame *f;<br> int chan_list_state;<br> <br>+ if (ast_thread_is_user_interface()) {<br>+ /* User interface threads do not handle channel media. */<br>+ ast_debug(1, "Thread is a user interface, not removing channel %s from autoservice\n",<br>+ ast_channel_name(chan));<br>+ return 0;<br>+ }<br>+<br> AST_LIST_LOCK(&aslist);<br> <br> /* Save the autoservice channel list state. We _must_ verify that the channel<br>diff --git a/main/tcptls.c b/main/tcptls.c<br>index 7c3efb4..c5ab0b6 100644<br>--- a/main/tcptls.c<br>+++ b/main/tcptls.c<br>@@ -685,6 +685,19 @@<br> return NULL;<br> }<br> <br>+ /*<br>+ * TCP/TLS connections are associated with external protocols which can<br>+ * be considered to be user interfaces (even for SIP messages), and<br>+ * will not handle channel media. This may need to be pushed down into<br>+ * the individual protocol handlers, but this seems like a good start.<br>+ */<br>+ if (ast_thread_user_interface_set(1)) {<br>+ ast_log(LOG_ERROR, "Failed to set user interface status; killing connection\n");<br>+ ast_tcptls_close_session_file(tcptls_session);<br>+ ao2_ref(tcptls_session, -1);<br>+ return NULL;<br>+ }<br>+<br> tcptls_session->stream_cookie = tcptls_stream_alloc();<br> if (!tcptls_session->stream_cookie) {<br> ast_tcptls_close_session_file(tcptls_session);<br>diff --git a/main/utils.c b/main/utils.c<br>index 2e612c1..ba16e41 100644<br>--- a/main/utils.c<br>+++ b/main/utils.c<br>@@ -2833,3 +2833,38 @@<br> <br> return 0;<br> }<br>+<br>+/*!<br>+ * \brief A thread local indicating whether the current thread is a user interface.<br>+ */<br>+AST_THREADSTORAGE(thread_user_interface_tl);<br>+<br>+int ast_thread_user_interface_set(int is_user_interface)<br>+{<br>+ int *thread_user_interface;<br>+<br>+ thread_user_interface = ast_threadstorage_get(<br>+ &thread_user_interface_tl, sizeof(*thread_user_interface));<br>+ if (thread_user_interface == NULL) {<br>+ ast_log(LOG_ERROR, "Error setting user interface status for current thread\n");<br>+ return -1;<br>+ }<br>+<br>+ *thread_user_interface = !!is_user_interface;<br>+ return 0;<br>+}<br>+<br>+int ast_thread_is_user_interface(void)<br>+{<br>+ int *thread_user_interface;<br>+<br>+ thread_user_interface = ast_threadstorage_get(<br>+ &thread_user_interface_tl, sizeof(*thread_user_interface));<br>+ if (thread_user_interface == NULL) {<br>+ ast_log(LOG_ERROR, "Error checking thread's user interface status\n");<br>+ /* On error, assume that we are not a user interface thread */<br>+ return 0;<br>+ }<br>+<br>+ return *thread_user_interface;<br>+}<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9211">change 9211</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/9211"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: If2dc94ce15ddabf923ed1e2a65ea0ef56e013e49 </div>
<div style="display:none"> Gerrit-Change-Number: 9211 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean.bright@gmail.com> </div>