Module: kamailio
Branch: master
Commit: 0a3c15239a620474bbbc7f4d2f57dda0e9aa0f58
URL:
https://github.com/kamailio/kamailio/commit/0a3c15239a620474bbbc7f4d2f57dda…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2023-02-08T15:51:37+01:00
async: catch up on possible skipped slots due to slow tasks
---
Modified: src/modules/async/async_sleep.c
---
Diff:
https://github.com/kamailio/kamailio/commit/0a3c15239a620474bbbc7f4d2f57dda…
Patch:
https://github.com/kamailio/kamailio/commit/0a3c15239a620474bbbc7f4d2f57dda…
---
diff --git a/src/modules/async/async_sleep.c b/src/modules/async/async_sleep.c
index 02c3b8d488..d6dd41d3f1 100644
--- a/src/modules/async/async_sleep.c
+++ b/src/modules/async/async_sleep.c
@@ -271,9 +271,12 @@ int async_sleep(sip_msg_t *msg, int seconds, cfg_action_t *act, str
*cbname)
return 0;
}
+static unsigned int _async_timer_exec_last_slot = -1;
+
void async_timer_exec(unsigned int ticks, void *param)
{
- int slot;
+ unsigned int idx;
+ unsigned int slot;
async_item_t *ai;
sr_kemi_eng_t *keng = NULL;
str cbname = STR_NULL;
@@ -282,33 +285,55 @@ void async_timer_exec(unsigned int ticks, void *param)
if(_async_list_head == NULL)
return;
- slot = ticks % ASYNC_RING_SIZE;
+ idx = ticks % ASYNC_RING_SIZE;
- while(1) {
- lock_get(&_async_list_head->ring[slot].lock);
- ai = _async_list_head->ring[slot].lstart;
- if(ai != NULL)
- _async_list_head->ring[slot].lstart = ai->next;
- lock_release(&_async_list_head->ring[slot].lock);
+ if(idx == _async_timer_exec_last_slot) {
+ /* timer faster than 1sec */
+ return;
+ }
- if(ai == NULL)
- break;
- if(ai->ract != NULL) {
- tmb.t_continue(ai->tindex, ai->tlabel, ai->ract);
- ksr_msg_env_reset();
- } else {
- keng = sr_kemi_eng_get();
- if(keng != NULL && ai->cbname_len>0) {
- cbname.s = ai->cbname;
- cbname.len = ai->cbname_len;
- tmb.t_continue_cb(ai->tindex, ai->tlabel, &cbname, &evname);
+ if(_async_timer_exec_last_slot < 0) {
+ _async_timer_exec_last_slot = idx;
+ }
+ slot = (_async_timer_exec_last_slot + 1) % ASYNC_RING_SIZE;
+ if(slot != idx) {
+ LM_DBG("need to catch up from slot %u to %u (slots: %u)\n", slot, idx,
+ ASYNC_RING_SIZE);
+ }
+
+ do {
+ while(1) {
+ lock_get(&_async_list_head->ring[slot].lock);
+ ai = _async_list_head->ring[slot].lstart;
+ if(ai != NULL)
+ _async_list_head->ring[slot].lstart = ai->next;
+ lock_release(&_async_list_head->ring[slot].lock);
+
+ if(ai == NULL)
+ break;
+ if(ai->ract != NULL) {
+ tmb.t_continue(ai->tindex, ai->tlabel, ai->ract);
ksr_msg_env_reset();
} else {
- LM_WARN("no callback to be executed\n");
+ keng = sr_kemi_eng_get();
+ if(keng != NULL && ai->cbname_len>0) {
+ cbname.s = ai->cbname;
+ cbname.len = ai->cbname_len;
+ tmb.t_continue_cb(ai->tindex, ai->tlabel, &cbname, &evname);
+ ksr_msg_env_reset();
+ } else {
+ LM_WARN("no callback to be executed\n");
+ }
}
+ shm_free(ai);
}
- shm_free(ai);
- }
+ if(slot == idx) {
+ break;
+ }
+ slot = (slot + 1) % ASYNC_RING_SIZE;
+ } while(1);
+
+ _async_timer_exec_last_slot = idx;
}
void async_mstimer_exec(unsigned int ticks, void *param)