Example output: # asterisk -nrx 'sip show sched' Highwater = 5 schedcnt = 2 [0x7fad2c994690] __cleanup_registration : 0 [0x7fad2c96d6f0] __dialog_unlink_sched_items : 0 [0x7fad2c9ee320] __sched_check_pendings : 0 [0x7fad2c96ed20] __shutdown_mwi_subscription : 0 [0x7fad2c9e76f0] __sip_autodestruct : 0 [0x7fad2c978b50] __sip_cancel_destroy : 0 [0x7fad2c977670] __sip_scheddestroy : 0 [0x7fad2c96c7f0] __start_mwi_subscription : 0 [0x7fad2c96c240] __start_register_timeout : 0 [0x7fad2c96c4c0] __start_reregister_timeout : 0 [0x7fad2c96ccd0] __start_session_timer : 0 [0x7fad2c96d040] __start_t38_abort_timer : 0 [0x7fad2c96cf80] __stop_provisional_keepalive : 0 [0x7fad2c96c3f0] __stop_register_timeout : 0 [0x7fad2c96cec0] __stop_reinvite_retry : 0 [0x7fad2c96ce00] __stop_reinviteid : 0 [0x7fad2c96c180] __stop_retrans_pkt : 0 [0x7fad2c96ccb0] __stop_session_timer : 0 [0x7fad2c96caa0] __stop_t38_abort_timer : 0 [0x7fad2c96ca90] __update_provisional_keepalive : 0 [0x7fad2c96ca80] __update_provisional_keepalive_with_sdp : 0 [0x498ff0] ast_cc_available_timer_expire : 0 [0x7fad2c99a220] auto_congest : 0 [0x7fad2c97f160] expire_register : 0 [0x7fad2c977e00] network_change_sched_cb : 0 [0x7fad2c9a9c30] proc_session_timer : 0 [0x7fad2c975db0] publish_expire : 0 [0x7fad2c9ee0b0] reinvite_timeout : 0 [0x7fad2c9eb4c0] retrans_pkt : 0 [0x7fad2c9bc250] send_provisional_keepalive : 0 [0x7fad2c9b5370] send_provisional_keepalive_with_sdp : 0 [0x7fad2c96f730] sip_offer_timer_expire : 0 [0x7fad2c993200] sip_poke_noanswer : 0 [0x7fad2c9c0a60] sip_poke_peer_now : 0 [0x7fad2c9c0a00] sip_poke_peer_s : 0 [0x7fad2c9e3aa0] sip_reg_timeout : 0 [0x7fad2c9ee5b0] sip_reinvite_retry : 0 [0x7fad2c9e3990] sip_reregister : 0 [0x7fad2c973fc0] sip_send_keepalive : 0 [0x7fad2c9dafc0] sip_subscribe_mwi_do : 0 [0x7fad2c9b4eb0] sip_t38_abort : 0 [0x7fad2d05c040] : 2 diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e1f6f13301..ebdad7bea5 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1283,6 +1283,7 @@ static void mwi_event_cb(void *, struct stasis_subscription *, struct stasis_mes static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message); static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message); static void sip_keepalive_all_peers(void); +static int sip_send_keepalive(const void *data); #define peer_in_destruction(peer) (ao2_ref(peer, 0) == 0) /*--- Applications, functions, CLI and manager command helpers */ @@ -1490,6 +1491,7 @@ static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struc /*------ T38 Support --------- */ static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans); static void change_t38_state(struct sip_pvt *p, int state); +static int sip_t38_abort(const void *data); /*------ Session-Timers functions --------- */ static void proc_422_rsp(struct sip_pvt *p, struct sip_request *rsp); @@ -1519,6 +1521,17 @@ static void stop_reinvite_retry(struct sip_pvt *pvt); static void stop_retrans_pkt(struct sip_pkt *pkt); static void stop_t38_abort_timer(struct sip_pvt *pvt); +/* More scheduler functions. */ +static int __cleanup_registration(const void *data); +static int __sched_check_pendings(const void *data); +static int __start_session_timer(const void *data); +static int __start_t38_abort_timer(const void *data); +static int __stop_register_timeout(const void *data); +static int __stop_reinvite_retry(const void *data); +static int __stop_session_timer(const void *data); +static int __stop_t38_abort_timer(const void *data); +static int proc_session_timer(const void *data); + /*! \brief Definition of this channel for PBX channel registration */ struct ast_channel_tech sip_tech = { .type = "SIP", @@ -21344,33 +21357,57 @@ static char *sip_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_str *cbuf; - struct ast_cb_names cbnames = { - 10, - { - "retrans_pkt", - "__sip_autodestruct", - "expire_register", - "auto_congest", - "sip_reg_timeout", - "sip_poke_peer_s", - "sip_poke_peer_now", - "sip_poke_noanswer", - "sip_reregister", - "sip_reinvite_retry" - }, - { - retrans_pkt, - __sip_autodestruct, - expire_register, - auto_congest, - sip_reg_timeout, - sip_poke_peer_s, - sip_poke_peer_now, - sip_poke_noanswer, - sip_reregister, - sip_reinvite_retry - } +#define CB(name) { #name , name } + struct ast_cb_item cbitems[] = { + CB(__cleanup_registration), /* void */ + CB(__dialog_unlink_sched_items), /* void */ + CB(__sched_check_pendings), /* void */ + CB(__shutdown_mwi_subscription), /* void */ + CB(__sip_autodestruct), /* pvt->autokillid */ + CB(__sip_cancel_destroy), /* void */ + CB(__sip_scheddestroy), /* void */ + CB(__start_mwi_subscription), /* void */ + CB(__start_register_timeout), /* void */ + CB(__start_reregister_timeout), /* void */ + CB(__start_session_timer), /* void */ + CB(__start_t38_abort_timer), /* void */ + CB(__stop_provisional_keepalive), /* void */ + CB(__stop_register_timeout), /* void */ + CB(__stop_reinvite_retry), /* void */ + CB(__stop_reinviteid), /* void */ + CB(__stop_retrans_pkt), /* void */ + CB(__stop_session_timer), /* void */ + CB(__stop_t38_abort_timer), /* void */ + CB(__update_provisional_keepalive), /* void */ + CB(__update_provisional_keepalive_with_sdp), /* void */ + CB(ast_cc_available_timer_expire), /* available_timer_id */ + CB(auto_congest), /* p->initid */ + CB(expire_register), /* peer->expire */ + CB(network_change_sched_cb), /* network_change_sched_id */ + CB(proc_session_timer), /* stimer->st_schedid */ + CB(publish_expire), /* esc_entry->sched_id */ + CB(reinvite_timeout), /* p->reinviteid */ + CB(retrans_pkt), /* pkt->retransid */ + CB(send_provisional_keepalive), /* pvt->provisional_keepalive_sched_id */ + CB(send_provisional_keepalive_with_sdp), /* pvt->provisional_keepalive_sched_id */ + CB(sip_offer_timer_expire), /* agent_pvt->offer_timer_id */ + CB(sip_poke_noanswer), /* peer->pokeexpire */ + CB(sip_poke_peer_now), /* peer->pokeexpire */ + CB(sip_poke_peer_s), /* peer->pokeexpire */ + CB(sip_reg_timeout), /* reg->timeout */ + CB(sip_reinvite_retry), /* p->waitid */ + CB(sip_reregister), /* reg->expire */ + CB(sip_send_keepalive), /* peer->keepalivesend */ + CB(sip_subscribe_mwi_do), /* mwi->resub */ + CB(sip_t38_abort) /* pvt->t38id */ + /* Additionally, ast_udptl_new_with_bindaddr and + * ast_rtp_instance_new also get sched, so they can + * attach other callbacks as well. Most common other + * callback is probably ast_rtcp_write from + * res_rtp_asterisk. */ }; +#undef CB + const unsigned cblen = ARRAY_LEN(cbitems); switch (cmd) { case CLI_INIT: @@ -21383,10 +21420,10 @@ static char *sip_show_sched(struct ast_cli_entry *e, int cmd, struct ast_cli_arg return NULL; } - cbuf = ast_str_alloca(2048); + cbuf = ast_str_alloca(4096); ast_cli(a->fd, "\n"); - ast_sched_report(sched, &cbuf, &cbnames); + ast_sched_report(sched, &cbuf, cblen, cbitems); ast_cli(a->fd, "%s", ast_str_buffer(cbuf)); return CLI_SUCCESS; diff --git a/include/asterisk/sched.h b/include/asterisk/sched.h index 804b05c0c9..6c2f9f8655 100644 --- a/include/asterisk/sched.h +++ b/include/asterisk/sched.h @@ -181,20 +181,20 @@ typedef int (*ast_sched_cb)(const void *data); */ void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb); -struct ast_cb_names { - int numassocs; - char *list[10]; - ast_sched_cb cblist[10]; +struct ast_cb_item { + const char *name; + ast_sched_cb cb; }; /*! * \brief Show statics on what it is in the schedule queue * \param con Schedule context to check * \param buf dynamic string to store report - * \param cbnames to check against + * \param cblen length of list of items to check against + * \param cbitems list of items to check against * \since 1.6.1 */ -void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames); +void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, unsigned cblen, struct ast_cb_item *cbitems); /*! * \brief Adds a scheduled event diff --git a/main/sched.c b/main/sched.c index e5a6e5210b..5f454b198c 100644 --- a/main/sched.c +++ b/main/sched.c @@ -660,14 +660,17 @@ int ast_sched_del(struct ast_sched_context *con, int id) return 0; } -void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, struct ast_cb_names *cbnames) +void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, unsigned cblen, struct ast_cb_item *cbitems) { - int i, x; + const unsigned max_other = 10; + void *othercb[max_other]; + int i, j, x; struct sched *cur; - int countlist[cbnames->numassocs + 1]; + int countlist[cblen + max_other + 1]; size_t heap_size; memset(countlist, 0, sizeof(countlist)); + memset(othercb, 0, sizeof(othercb)); ast_str_set(buf, 0, " Highwater = %u\n schedcnt = %zu\n", con->highwater, ast_heap_size(con->sched_heap)); ast_mutex_lock(&con->lock); @@ -676,25 +679,39 @@ void ast_sched_report(struct ast_sched_context *con, struct ast_str **buf, struc for (x = 1; x <= heap_size; x++) { cur = ast_heap_peek(con->sched_heap, x); /* match the callback to the cblist */ - for (i = 0; i < cbnames->numassocs; i++) { - if (cur->callback == cbnames->cblist[i]) { + for (i = 0; i < cblen; i++) { + if (cur->callback == cbitems[i].cb) { break; } } - if (i < cbnames->numassocs) { - countlist[i]++; - } else { - countlist[cbnames->numassocs]++; + /* no match? check list of unknown callbacks */ + if (i == cblen) { + for (j = 0; j < max_other; ++i, ++j) { + if (cur->callback == othercb[j]) { + break; + } + othercb[j] = cur->callback; + break; + } } + countlist[i]++; } ast_mutex_unlock(&con->lock); - for (i = 0; i < cbnames->numassocs; i++) { - ast_str_append(buf, 0, " %s : %d\n", cbnames->list[i], countlist[i]); + for (i = 0; i < cblen; ++i) { + ast_str_append(buf, 0, " [%p] %s : %d\n", cbitems[i].cb, cbitems[i].name, countlist[i]); + } + for (j = 0; j < max_other && othercb[j]; ++i, ++j) { + /* This won't get you the name, but some debugging will help you out: + * (gdb) info line *0x7fad2d05c040 + * Line 3899 of "res_rtp_asterisk.c" starts at address 0x7fad2d05c040 + * and ends at 0x7fad2d05c044 . */ + ast_str_append(buf, 0, " [%p] : %d\n", othercb[j], countlist[i]); + } + if (countlist[cblen + max_other]) { + ast_str_append(buf, 0, " : %d\n", countlist[cblen + max_other]); } - - ast_str_append(buf, 0, " : %d\n", countlist[cbnames->numassocs]); } /*! \brief Dump the contents of the scheduler to LOG_DEBUG */