diff options
-rw-r--r-- | include/asterisk/res_pjsip.h | 15 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_scheduler.c | 62 |
2 files changed, 59 insertions, 18 deletions
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index e937018f2..092bb8420 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -1684,16 +1684,23 @@ enum ast_sip_scheduler_task_flags { */ AST_SIP_SCHED_TASK_DATA_FREE = ( 1 << 3 ), - /*! \brief AST_SIP_SCHED_TASK_PERIODIC - * The task is scheduled at multiples of interval + /*! + * \brief The task is scheduled at multiples of interval * \see Interval */ AST_SIP_SCHED_TASK_PERIODIC = (0 << 4), - /*! \brief AST_SIP_SCHED_TASK_DELAY - * The next invocation of the task is at last finish + interval + /*! + * \brief The next invocation of the task is at last finish + interval * \see Interval */ AST_SIP_SCHED_TASK_DELAY = (1 << 4), + /*! + * \brief The scheduled task's events are tracked in the debug log. + * \details + * Schedule events such as scheduling, running, rescheduling, canceling, + * and destroying are logged about the task. + */ + AST_SIP_SCHED_TASK_TRACK = (1 << 5), }; /*! diff --git a/res/res_pjsip/pjsip_scheduler.c b/res/res_pjsip/pjsip_scheduler.c index 4210664dc..bbf666fd7 100644 --- a/res/res_pjsip/pjsip_scheduler.c +++ b/res/res_pjsip/pjsip_scheduler.c @@ -86,6 +86,9 @@ static int run_task(void *data) return -1; } + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Running %s\n", schtd, schtd->name); + } ao2_lock(schtd); schtd->last_start = ast_tvnow(); schtd->is_running = 1; @@ -137,6 +140,10 @@ static int run_task(void *data) } ao2_unlock(schtd); + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Rescheduled %s for %d ms\n", schtd, schtd->name, + delay); + } return 0; } @@ -159,6 +166,9 @@ static int push_to_serializer(const void *data) return 0; } + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Ready to run %s\n", schtd, schtd->name); + } ao2_t_ref(schtd, +1, "Give ref to run_task()"); if (ast_sip_push_task(schtd->serializer, run_task, schtd)) { /* @@ -181,6 +191,10 @@ int ast_sip_sched_task_cancel(struct ast_sip_sched_task *schtd) int res; int sched_id; + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Canceling %s\n", schtd, schtd->name); + } + /* * Prevent any tasks in the serializer queue from * running and restarting the scheduled item on us @@ -347,6 +361,9 @@ static void schtd_dtor(void *data) { struct ast_sip_sched_task *schtd = data; + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Destructor %s\n", schtd, schtd->name); + } if (schtd->flags & AST_SIP_SCHED_TASK_DATA_AO2) { /* release our own ref, then release the callers if asked to do so */ ao2_ref(schtd->task_data, (schtd->flags & AST_SIP_SCHED_TASK_DATA_FREE) ? -2 : -1); @@ -387,6 +404,10 @@ struct ast_sip_sched_task *ast_sip_schedule_task(struct ast_taskprocessor *seria task_id = ast_atomic_fetchadd_int(&task_count, 1); sprintf(schtd->name, "task_%08x", task_id); } + if (schtd->flags & AST_SIP_SCHED_TASK_TRACK) { + ast_log(LOG_DEBUG, "Sched %p: Scheduling %s for %d ms\n", schtd, schtd->name, + interval); + } schtd->when_queued = ast_tvnow(); if (!(schtd->flags & AST_SIP_SCHED_TASK_DELAY)) { schtd->next_periodic = ast_tvadd(schtd->when_queued, @@ -426,7 +447,8 @@ struct ast_sip_sched_task *ast_sip_schedule_task(struct ast_taskprocessor *seria static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct ao2_iterator i; + struct ao2_iterator iter; + struct ao2_container *sorted_tasks; struct ast_sip_sched_task *schtd; const char *log_format; struct ast_tm tm; @@ -435,7 +457,7 @@ static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_arg char next_start[32]; int datelen; struct timeval now; - static const char separator[] = "======================================"; + static const char separator[] = "============================================="; switch (cmd) { case CLI_INIT: @@ -451,6 +473,17 @@ static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_arg return CLI_SHOWUSAGE; } + /* Get a sorted snapshot of the scheduled tasks */ + sorted_tasks = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, + ast_sip_sched_task_sort_fn, NULL); + if (!sorted_tasks) { + return CLI_SUCCESS; + } + if (ao2_container_dup(sorted_tasks, tasks, 0)) { + ao2_ref(sorted_tasks, -1); + return CLI_SUCCESS; + } + now = ast_tvnow(); log_format = ast_logger_get_dateformat(); @@ -459,25 +492,28 @@ static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_arg ast_cli(a->fd, "PJSIP Scheduled Tasks:\n\n"); - ast_cli(a->fd, " %1$-24s %2$-9s %3$-9s %4$-5s %6$-*5$s %7$-*5$s %8$-*5$s %9$7s\n", + ast_cli(a->fd, "%1$-45s %2$-9s %3$-9s %4$-5s %6$-*5$s %7$-*5$s %8$-*5$s %9$7s\n", "Task Name", "Interval", "Times Run", "State", datelen, "Queued", "Last Started", "Next Start", "( secs)"); - ast_cli(a->fd, " %1$-24.24s %2$-9.9s %3$-9.9s %4$-5.5s %6$-*5$.*5$s %7$-*5$.*5$s %9$-*8$.*8$s\n", + 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", separator, separator, separator, separator, datelen, separator, separator, datelen + 8, separator); - - ao2_rdlock(tasks); - i = ao2_iterator_init(tasks, AO2_ITERATOR_DONTLOCK); - while ((schtd = ao2_iterator_next(&i))) { + iter = ao2_iterator_init(sorted_tasks, AO2_ITERATOR_UNLINK); + for (; (schtd = ao2_iterator_next(&iter)); ao2_ref(schtd, -1)) { int next_run_sec; struct timeval next; ao2_lock(schtd); next_run_sec = ast_sip_sched_task_get_next_run(schtd) / 1000; - next = ast_tvadd(now, (struct timeval) {next_run_sec, 0}); + if (next_run_sec < 0) { + /* Scheduled task is now canceled */ + ao2_unlock(schtd); + continue; + } + next = ast_tvadd(now, ast_tv(next_run_sec, 0)); ast_localtime(&schtd->when_queued, &tm, NULL); ast_strftime(queued, sizeof(queued), log_format, &tm); @@ -492,7 +528,7 @@ static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_arg ast_localtime(&next, &tm, NULL); ast_strftime(next_start, sizeof(next_start), log_format, &tm); - ast_cli(a->fd, " %1$-24.24s %2$9.3f %3$9d %4$-5s %6$-*5$s %7$-*5$s %8$-*5$s (%9$5d)\n", + 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", schtd->name, schtd->interval / 1000.0, schtd->run_count, @@ -501,11 +537,9 @@ static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_arg next_start, next_run_sec); ao2_unlock(schtd); - - ao2_cleanup(schtd); } - ao2_iterator_destroy(&i); - ao2_unlock(tasks); + ao2_iterator_destroy(&iter); + ao2_ref(sorted_tasks, -1); ast_cli(a->fd, "\n"); return CLI_SUCCESS; |