<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/9216">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/16/9216/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 b6fd9e8..1fc7b42 100644<br>--- a/include/asterisk/utils.h<br>+++ b/include/asterisk/utils.h<br>@@ -1194,4 +1194,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 cd7388b..8ff2cb5 100644<br>--- a/main/autoservice.c<br>+++ b/main/autoservice.c<br>@@ -202,6 +202,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>@@ -263,6 +270,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 f555730..3ba52ff 100644<br>--- a/main/tcptls.c<br>+++ b/main/tcptls.c<br>@@ -134,6 +134,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>  if (tcptls_session->parent->tls_cfg) {<br> #ifdef DO_SSL<br>          if (ast_iostream_start_tls(&tcptls_session->stream, tcptls_session->parent->tls_cfg->ssl_ctx, tcptls_session->client) < 0) {<br>diff --git a/main/utils.c b/main/utils.c<br>index dae994d..b249f6a 100644<br>--- a/main/utils.c<br>+++ b/main/utils.c<br>@@ -2793,3 +2793,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/9216">change 9216</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/9216"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </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: 9216 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>