<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/9211">View Change</a></p><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;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/11/9211/1</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: newchange </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>