<p>Kevin Harwell <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15131">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve; Approved for Submit
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pjsip_scheduler.c: Add type ONESHOT and enhance cli show command<br><br>* Added a ONESHOT type that never reschedules.<br><br>* Added "like" capability to "pjsip show scheduled_tasks" so you can do<br>  the following:<br><br>  CLI> pjsip show scheduled_tasks like outreg<br>  PJSIP Scheduled Tasks:<br><br>  Task Name                                     Interval  Times Run ...<br>  ============================================= ========= ========= ...<br>  pjsip/outreg/testtrunk-reg-0-00000074            50.000   oneshot ...<br>  pjsip/outreg/voipms-reg-0-00000073              110.000   oneshot ...<br><br>* Fixed incorrect display of "Next Start".<br><br>* Compacted the displays of times in the CLI.<br><br>* Added two new functions (ast_sip_sched_task_get_times2,<br>  ast_sip_sched_task_get_times_by_name2) that retrieve the interval,<br>  next start time, and next run time in addition to the times already<br>  returned by ast_sip_sched_task_get_times().<br><br>Change-Id: Ie718ca9fd30490b8a167bedf6b0b06d619dc52f3<br>---<br>M include/asterisk/res_pjsip.h<br>M res/res_pjsip/pjsip_scheduler.c<br>2 files changed, 167 insertions(+), 59 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h</span><br><span>index 07edcec..5e3e439 100644</span><br><span>--- a/include/asterisk/res_pjsip.h</span><br><span>+++ b/include/asterisk/res_pjsip.h</span><br><span>@@ -1785,6 +1785,12 @@</span><br><span>        AST_SIP_SCHED_TASK_VARIABLE = (1 << 0),</span><br><span> </span><br><span>    /*!</span><br><span style="color: hsl(120, 100%, 40%);">+    * Run just once.</span><br><span style="color: hsl(120, 100%, 40%);">+      * Return values are ignored.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_SIP_SCHED_TASK_ONESHOT = (1 << 6),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /*!</span><br><span>   * The task data is not an AO2 object.</span><br><span>        */</span><br><span>  AST_SIP_SCHED_TASK_DATA_NOT_AO2 = (0 << 1),</span><br><span>@@ -1906,6 +1912,26 @@</span><br><span>   struct timeval *when_queued, struct timeval *last_start, struct timeval *last_end);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Gets the queued, last start, last_end, time left, interval, next run</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.15.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 18.1.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param schtd The task structure pointer</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] when_queued Pointer to a timeval structure to contain the time when queued</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_start Pointer to a timeval structure to contain the time when last started</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_end Pointer to a timeval structure to contain the time when last ended</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] interval Pointer to an int to contain the interval in ms</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] time_left Pointer to an int to contain the ms left to the next run</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_end Pointer to a timeval structure to contain the next run time</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note Any of the pointers can be NULL if you don't need them.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times2(struct ast_sip_sched_task *schtd,</span><br><span style="color: hsl(120, 100%, 40%);">+      struct timeval *when_queued, struct timeval *last_start, struct timeval *last_end,</span><br><span style="color: hsl(120, 100%, 40%);">+    int *interval, int *time_left, struct timeval *next_start);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Gets the last start and end times of the task by name</span><br><span>  * \since 13.9.0</span><br><span>  *</span><br><span>@@ -1921,6 +1947,26 @@</span><br><span>     struct timeval *when_queued, struct timeval *last_start, struct timeval *last_end);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Gets the queued, last start, last_end, time left, interval, next run by task name</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.15.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 18.1.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param name The task name</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] when_queued Pointer to a timeval structure to contain the time when queued</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_start Pointer to a timeval structure to contain the time when last started</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_end Pointer to a timeval structure to contain the time when last ended</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] interval Pointer to an int to contain the interval in ms</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] time_left Pointer to an int to contain the ms left to the next run</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] last_end Pointer to a timeval structure to contain the next run time</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \note Any of the pointers can be NULL if you don't need them.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times_by_name2(const char *name,</span><br><span style="color: hsl(120, 100%, 40%);">+       struct timeval *when_queued, struct timeval *last_start, struct timeval *last_end,</span><br><span style="color: hsl(120, 100%, 40%);">+    int *interval, int *time_left, struct timeval *next_start);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Gets the number of milliseconds until the next invocation</span><br><span>  * \since 13.9.0</span><br><span>  *</span><br><span>diff --git a/res/res_pjsip/pjsip_scheduler.c b/res/res_pjsip/pjsip_scheduler.c</span><br><span>index bbf666f..ac53379 100644</span><br><span>--- a/res/res_pjsip/pjsip_scheduler.c</span><br><span>+++ b/res/res_pjsip/pjsip_scheduler.c</span><br><span>@@ -30,6 +30,8 @@</span><br><span> #include "asterisk/res_pjsip_cli.h"</span><br><span> #include "asterisk/taskprocessor.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <regex.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define TASK_BUCKETS 53</span><br><span> </span><br><span> static struct ast_sched_context *scheduler_context;</span><br><span>@@ -105,7 +107,7 @@</span><br><span>        * Don't restart if the task returned <= 0 or if the interval</span><br><span>          * was set to 0 while the task was running</span><br><span>    */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (res <= 0 || !schtd->interval) {</span><br><span style="color: hsl(120, 100%, 40%);">+     if ((schtd->flags & AST_SIP_SCHED_TASK_ONESHOT) || res <= 0 || !schtd->interval) {</span><br><span>              schtd->interval = 0;</span><br><span>              ao2_unlock(schtd);</span><br><span>           ao2_unlink(tasks, schtd);</span><br><span>@@ -232,9 +234,9 @@</span><br><span>      return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int ast_sip_sched_task_get_times(struct ast_sip_sched_task *schtd,</span><br><span style="color: hsl(0, 100%, 40%);">-  struct timeval *queued, struct timeval *last_start, struct timeval *last_end)</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times2(struct ast_sip_sched_task *schtd,</span><br><span style="color: hsl(120, 100%, 40%);">+    struct timeval *queued, struct timeval *last_start, struct timeval *last_end,</span><br><span style="color: hsl(120, 100%, 40%);">+ int *interval, int *time_left, struct timeval *next_start)</span><br><span> {</span><br><span>      ao2_lock(schtd);</span><br><span>     if (queued) {</span><br><span>@@ -246,14 +248,64 @@</span><br><span>        if (last_end) {</span><br><span>              memcpy(last_end, &schtd->last_end, sizeof(struct timeval));</span><br><span>   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (interval) {</span><br><span style="color: hsl(120, 100%, 40%);">+               *interval = schtd->interval;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (time_left || next_start) {</span><br><span style="color: hsl(120, 100%, 40%);">+                int delay;</span><br><span style="color: hsl(120, 100%, 40%);">+            struct timeval since_when;</span><br><span style="color: hsl(120, 100%, 40%);">+            struct timeval now;</span><br><span style="color: hsl(120, 100%, 40%);">+           struct timeval next;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (schtd->interval) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     delay = schtd->interval;</span><br><span style="color: hsl(120, 100%, 40%);">+                   now = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (schtd->flags & AST_SIP_SCHED_TASK_DELAY) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         since_when = schtd->is_running ? now : schtd->last_end;</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              since_when = schtd->last_start.tv_sec ? schtd->last_start : schtd->when_queued;</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   delay -= ast_tvdiff_ms(now, since_when);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    delay = delay < 0 ? 0 : delay;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (time_left) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              *time_left = delay;</span><br><span style="color: hsl(120, 100%, 40%);">+                   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (next_start) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             next = ast_tvadd(now, ast_tv(delay / 1000, (delay % 1000) * 1000));</span><br><span style="color: hsl(120, 100%, 40%);">+                           memcpy(next_start, &next, sizeof(struct timeval));</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (time_left) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              *time_left = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  ao2_unlock(schtd);</span><br><span> </span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int ast_sip_sched_task_get_times_by_name(const char *name,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times(struct ast_sip_sched_task *schtd,</span><br><span>   struct timeval *queued, struct timeval *last_start, struct timeval *last_end)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+    return ast_sip_sched_task_get_times2(schtd, queued, last_start, last_end, NULL, NULL, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times_by_name2(const char *name,</span><br><span style="color: hsl(120, 100%, 40%);">+        struct timeval *queued, struct timeval *last_start, struct timeval *last_end,</span><br><span style="color: hsl(120, 100%, 40%);">+ int *interval, int *time_left, struct timeval *next_start)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span>        int res;</span><br><span>     struct ast_sip_sched_task *schtd;</span><br><span> </span><br><span>@@ -266,11 +318,19 @@</span><br><span>                return -1;</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   res = ast_sip_sched_task_get_times(schtd, queued, last_start, last_end);</span><br><span style="color: hsl(120, 100%, 40%);">+      res = ast_sip_sched_task_get_times2(schtd, queued, last_start, last_end, interval, time_left,</span><br><span style="color: hsl(120, 100%, 40%);">+         next_start);</span><br><span>         ao2_ref(schtd, -1);</span><br><span>  return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sip_sched_task_get_times_by_name(const char *name,</span><br><span style="color: hsl(120, 100%, 40%);">+      struct timeval *queued, struct timeval *last_start, struct timeval *last_end)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return ast_sip_sched_task_get_times_by_name2(name, queued, last_start, last_end,</span><br><span style="color: hsl(120, 100%, 40%);">+              NULL, NULL, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int ast_sip_sched_task_get_name(struct ast_sip_sched_task *schtd, char *name, size_t maxlen)</span><br><span> {</span><br><span>         if (maxlen <= 0) {</span><br><span>@@ -287,29 +347,8 @@</span><br><span> int ast_sip_sched_task_get_next_run(struct ast_sip_sched_task *schtd)</span><br><span> {</span><br><span>   int delay;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct timeval since_when;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct timeval now;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ao2_lock(schtd);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (schtd->interval) {</span><br><span style="color: hsl(0, 100%, 40%);">-               delay = schtd->interval;</span><br><span style="color: hsl(0, 100%, 40%);">-             now = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (schtd->flags & AST_SIP_SCHED_TASK_DELAY) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   since_when = schtd->is_running ? now : schtd->last_end;</span><br><span style="color: hsl(0, 100%, 40%);">-           } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        since_when = schtd->last_start.tv_sec ? schtd->last_start : schtd->when_queued;</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               delay -= ast_tvdiff_ms(now, since_when);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                delay = delay < 0 ? 0 : delay;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                delay = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ao2_unlock(schtd);</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_sched_task_get_times2(schtd, NULL, NULL, NULL, NULL, &delay, NULL);</span><br><span> </span><br><span>  return delay;</span><br><span> }</span><br><span>@@ -396,6 +435,7 @@</span><br><span>     schtd->task = sip_task;</span><br><span>   schtd->interval = interval;</span><br><span>       schtd->flags = flags;</span><br><span style="color: hsl(120, 100%, 40%);">+      schtd->last_start = ast_tv(0, 0);</span><br><span>         if (!ast_strlen_zero(name)) {</span><br><span>                strcpy(schtd->name, name); /* Safe */</span><br><span>     } else {</span><br><span>@@ -445,60 +485,75 @@</span><br><span> #undef ID_LEN</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define TIME_FORMAT "%a %T"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span> {</span><br><span>    struct ao2_iterator iter;</span><br><span>    struct ao2_container *sorted_tasks;</span><br><span>  struct ast_sip_sched_task *schtd;</span><br><span style="color: hsl(0, 100%, 40%);">-       const char *log_format;</span><br><span>      struct ast_tm tm;</span><br><span style="color: hsl(120, 100%, 40%);">+     char times_run[16];</span><br><span>  char queued[32];</span><br><span>     char last_start[32];</span><br><span>         char next_start[32];</span><br><span style="color: hsl(0, 100%, 40%);">-    int datelen;</span><br><span>         struct timeval now;</span><br><span style="color: hsl(0, 100%, 40%);">-     static const char separator[] = "=============================================";</span><br><span style="color: hsl(120, 100%, 40%);">+    int using_regex = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  regex_t regex;</span><br><span> </span><br><span>   switch (cmd) {</span><br><span>       case CLI_INIT:</span><br><span>               e->command = "pjsip show scheduled_tasks";</span><br><span style="color: hsl(0, 100%, 40%);">-         e->usage = "Usage: pjsip show scheduled_tasks\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                       "      Show all scheduled tasks\n";</span><br><span style="color: hsl(120, 100%, 40%);">+             e->usage = "Usage: pjsip show scheduled_tasks [ like <pattern> ]\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                            "      Show scheduled pjsip tasks\n";</span><br><span>          return NULL;</span><br><span>         case CLI_GENERATE:</span><br><span>           return NULL;</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (a->argc != 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (a->argc != 3 && a->argc != 5) {</span><br><span>            return CLI_SHOWUSAGE;</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (a->argc == 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+                int regrc;</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!strcasecmp(a->argv[3], "like") == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      return CLI_SHOWUSAGE;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             regrc = regcomp(&regex, a->argv[4], REG_EXTENDED | REG_ICASE | REG_NOSUB);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (regrc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  char err[256];</span><br><span style="color: hsl(120, 100%, 40%);">+                        regerror(regrc, &regex, err, 256);</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_cli(a->fd, "PJSIP Scheduled Tasks: Error: %s\n", err);</span><br><span style="color: hsl(120, 100%, 40%);">+                       return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             using_regex = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /* Get a sorted snapshot of the scheduled tasks */</span><br><span>   sorted_tasks = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,</span><br><span>              ast_sip_sched_task_sort_fn, NULL);</span><br><span>   if (!sorted_tasks) {</span><br><span style="color: hsl(0, 100%, 40%);">-            return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_cli(a->fd, "PJSIP Scheduled Tasks: Unable to allocate temporary container\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return CLI_FAILURE;</span><br><span>  }</span><br><span>    if (ao2_container_dup(sorted_tasks, tasks, 0)) {</span><br><span>             ao2_ref(sorted_tasks, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-              return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_cli(a->fd, "PJSIP Scheduled Tasks: Unable to sort temporary container\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return CLI_FAILURE;</span><br><span>  }</span><br><span> </span><br><span>        now = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">-      log_format = ast_logger_get_dateformat();</span><br><span> </span><br><span>        ast_localtime(&now, &tm, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- datelen = ast_strftime(queued, sizeof(queued), log_format, &tm);</span><br><span> </span><br><span>     ast_cli(a->fd, "PJSIP Scheduled Tasks:\n\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  ast_cli(a->fd, "%1$-45s %2$-9s %3$-9s %4$-5s  %6$-*5$s  %7$-*5$s  %8$-*5$s %9$7s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-               "Task Name", "Interval", "Times Run", "State",</span><br><span style="color: hsl(0, 100%, 40%);">-          datelen, "Queued", "Last Started", "Next Start", "( secs)");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ast_cli(a->fd, "%1$-45.45s %2$-9.9s %3$-9.9s %4$-5.5s  %6$-*5$.*5$s  %7$-*5$.*5$s  %9$-*8$.*8$s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                separator, separator, separator, separator,</span><br><span style="color: hsl(0, 100%, 40%);">-             datelen, separator, separator, datelen + 8, separator);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_cli(a->fd,</span><br><span style="color: hsl(120, 100%, 40%);">+             "<Task Name....................................> <Interval> <Times Run> <State>"</span><br><span style="color: hsl(120, 100%, 40%);">+            "  <Queued....>  <Last Start>  <Next Start.....secs>\n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "=============================================================================="</span><br><span style="color: hsl(120, 100%, 40%);">+            "===================================================\n");</span><br><span> </span><br><span>      iter = ao2_iterator_init(sorted_tasks, AO2_ITERATOR_UNLINK);</span><br><span>         for (; (schtd = ao2_iterator_next(&iter)); ao2_ref(schtd, -1)) {</span><br><span>@@ -507,6 +562,11 @@</span><br><span> </span><br><span>              ao2_lock(schtd);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+          if (using_regex && regexec(&regex, schtd->name, 0, NULL, 0) == REG_NOMATCH) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  ao2_unlock(schtd);</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          next_run_sec = ast_sip_sched_task_get_next_run(schtd) / 1000;</span><br><span>                if (next_run_sec < 0) {</span><br><span>                   /* Scheduled task is now canceled */</span><br><span>@@ -516,37 +576,39 @@</span><br><span>                 next = ast_tvadd(now, ast_tv(next_run_sec, 0));</span><br><span> </span><br><span>          ast_localtime(&schtd->when_queued, &tm, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_strftime(queued, sizeof(queued), log_format, &tm);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_strftime(queued, sizeof(queued), TIME_FORMAT, &tm);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         if (ast_tvzero(schtd->last_start)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 strcpy(last_start, "not yet started");</span><br><span style="color: hsl(0, 100%, 40%);">-                } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_localtime(&schtd->last_start, &tm, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                        ast_strftime(last_start, sizeof(last_start), log_format, &tm);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_localtime(&schtd->last_start, &tm, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_strftime(last_start, sizeof(last_start), TIME_FORMAT, &tm);</span><br><span> </span><br><span>              ast_localtime(&next, &tm, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_strftime(next_start, sizeof(next_start), log_format, &tm);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_strftime(next_start, sizeof(next_start), TIME_FORMAT, &tm);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         ast_cli(a->fd, "%1$-46.46s%2$9.3f %3$9d %4$-5s  %6$-*5$s  %7$-*5$s  %8$-*5$s (%9$5d)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+         sprintf(times_run, "%d", schtd->run_count);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_cli(a->fd, "%-46.46s   %9d   %9s   %-5s  %-12s  %-12s  %-12s %8d\n",</span><br><span>                        schtd->name,</span><br><span style="color: hsl(0, 100%, 40%);">-                 schtd->interval / 1000.0,</span><br><span style="color: hsl(0, 100%, 40%);">-                    schtd->run_count,</span><br><span style="color: hsl(120, 100%, 40%);">+                  schtd->interval / 1000,</span><br><span style="color: hsl(120, 100%, 40%);">+                    schtd->flags & AST_SIP_SCHED_TASK_ONESHOT ? "oneshot" : times_run,</span><br><span>                  schtd->is_running ? "run" : "wait",</span><br><span style="color: hsl(0, 100%, 40%);">-                      datelen, queued, last_start,</span><br><span style="color: hsl(120, 100%, 40%);">+                  queued,</span><br><span style="color: hsl(120, 100%, 40%);">+                       (ast_tvzero(schtd->last_start) || (schtd->flags & AST_SIP_SCHED_TASK_ONESHOT) ? "" : last_start),</span><br><span>                        next_start,</span><br><span>                  next_run_sec);</span><br><span>               ao2_unlock(schtd);</span><br><span>   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (using_regex) {</span><br><span style="color: hsl(120, 100%, 40%);">+            regfree(&regex);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span>    ao2_iterator_destroy(&iter);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_cli(a->fd, "\nTotal Scheduled Tasks: %d\n\n", ao2_container_count(sorted_tasks));</span><br><span>   ao2_ref(sorted_tasks, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-      ast_cli(a->fd, "\n");</span><br><span> </span><br><span>       return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span> static struct ast_cli_entry cli_commands[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-  AST_CLI_DEFINE(cli_show_tasks, "Show all scheduled tasks"),</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_CLI_DEFINE(cli_show_tasks, "Show pjsip scheduled tasks"),</span><br><span> };</span><br><span> </span><br><span> int ast_sip_initialize_scheduler(void)</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15131">change 15131</a>. To unsubscribe, or for help writing mail filters, 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/c/asterisk/+/15131"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: Ie718ca9fd30490b8a167bedf6b0b06d619dc52f3 </div>
<div style="display:none"> Gerrit-Change-Number: 15131 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>