]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_stasis: signal when new command is queued
authorMike Bradeen <mbradeen@sangoma.com>
Mon, 2 Oct 2023 18:35:32 +0000 (12:35 -0600)
committerAsterisk Development Team <asteriskteam@digium.com>
Fri, 12 Jan 2024 18:32:12 +0000 (18:32 +0000)
res_statsis's app loop sleeps for up to .2s waiting on input
to a channel before re-checking the command queue. This can
cause delays between channel setup and bridge.

This change is to send a SIGURG on the sleeping thread when
a new command is enqueued. This exits the sleeping thread out
of the ast_waitfor() call triggering the new command being
processed on the channel immediately.

Resolves: #362

UserNote: Call setup times should be significantly improved
when using ARI.

(cherry picked from commit 7ea0e3bfdaa23aa3d2e9d88b2bf4016179233335)

res/res_stasis.c
res/stasis/control.c
res/stasis/control.h

index 84244c2a133a09bef6f3f3ecc5cab09780330759..6b4c30d8947d201b0cc72387ee7457fb2e8bca0a 100644 (file)
@@ -1548,7 +1548,11 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
                        continue;
                }
 
+               /* Set this thread's id as the control thread id so that any
+                  new commands can signal out of this wait */
+               control_set_thread(control, pthread_self());
                r = ast_waitfor(chan, MAX_WAIT_MS);
+               control_set_thread(control, AST_PTHREADT_NULL);
 
                if (r < 0) {
                        ast_debug(3, "%s: Poll error\n",
index 584e60ecfa76a5a522201bb47eec31204361b4c7..360f207900030dc4a11220cc6cd2cb53b519681f 100644 (file)
@@ -92,6 +92,10 @@ struct stasis_app_control {
         * The name of the next Stasis application to move to.
         */
        char *next_app;
+       /*!
+        * The thread currently blocking on the channel.
+        */
+       pthread_t control_thread;
        /*!
         * The list of arguments to pass to StasisStart when moving to another app.
         */
@@ -156,6 +160,8 @@ struct stasis_app_control *control_create(struct ast_channel *channel, struct st
        control->next_app = NULL;
        AST_VECTOR_INIT(&control->next_app_args, 0);
 
+       control_set_thread(control, AST_PTHREADT_NULL);
+
        return control;
 }
 
@@ -185,6 +191,13 @@ static void app_control_unregister_rule(
        ao2_unlock(control->command_queue);
 }
 
+void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
+{
+       ao2_lock(control->command_queue);
+       control->control_thread = threadid;
+       ao2_unlock(control->command_queue);
+}
+
 /*!
  * \internal
  * \brief Checks to make sure each rule in the given list passes.
@@ -293,6 +306,13 @@ static struct stasis_app_command *exec_command_on_condition(
 
        ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
        ast_cond_signal(&control->wait_cond);
+
+       if (control->control_thread != AST_PTHREADT_NULL) {
+               /* if the control thread is waiting on the channel, send the SIGURG
+                  to let it know there is a new command */
+               pthread_kill(control->control_thread, SIGURG);
+       }
+
        ao2_unlock(control->command_queue);
 
        return command;
index 137ac81557100688fbaa3294139410726c1ed063..3593f8a40ffda51ef03966f0e0c37c1b777d2fd0 100644 (file)
@@ -48,6 +48,15 @@ struct stasis_app_control *control_create(struct ast_channel *channel, struct st
  */
 void control_flush_queue(struct stasis_app_control *control);
 
+/*!
+ * \brief set the control's thread id
+ * \since 18
+ *
+ * \param control Control object on which to set the thread id.
+ * \param threadid id to set
+ */
+void control_set_thread(struct stasis_app_control *control, pthread_t threadid);
+
 /*!
  * \brief Dispatch all commands enqueued to this control.
  *