Skip to content

Commit

Permalink
[dispatcher] Improve probing by sending the probs outside locking
Browse files Browse the repository at this point in the history
Collect the data under locking, move the OPTIONs probing outside the locking, to be sure that any potential blocking on SIP level sending is not leading to lock starvation.
Simialar to 4c7a7a8 (drouting)
Related to #2438

(cherry picked from commit 8139e27)
(cherry picked from commit d65f37e)
(cherry picked from commit 322e9b9)
  • Loading branch information
bogdan-iancu committed Jan 31, 2023
1 parent 263afc9 commit 1461263
Showing 1 changed file with 84 additions and 32 deletions.
116 changes: 84 additions & 32 deletions modules/dispatcher/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -2502,9 +2502,22 @@ static void ds_options_callback( struct cell *t, int type,
*/
void ds_check_timer(unsigned int ticks, void* param)
{
struct gw_prob_pack {
/* IMPORTANT, this member must be the first, as we use its pointer
* to free the whole structure here */
ds_options_callback_param_t params;

struct socket_info *sock;
str uri;
struct usr_avp *avps;

struct gw_prob_pack *next;
};
ds_partition_t *partition;
struct gw_prob_pack *pack, *pack_last, *pack_head;
dlg_t *dlg;
ds_set_p list;
int_str val;
int j;

if ( !ds_cluster_shtag_is_active() )
Expand All @@ -2515,6 +2528,8 @@ void ds_check_timer(unsigned int ticks, void* param)
if ( (*partition->data)->sets==NULL )
continue;

pack_last = pack_head = NULL;

/* access ds data under reader's lock */
lock_start_read( partition->lock );

Expand All @@ -2533,47 +2548,84 @@ void ds_check_timer(unsigned int ticks, void* param)
LM_DBG("probing set #%d, URI %.*s\n", list->id,
list->dlist[j].uri.len, list->dlist[j].uri.s);

/* Execute the Dialog using the "request"-Method of the
* TM-Module.*/
if (tmb.new_auto_dlg_uac(&ds_ping_from,
&list->dlist[j].uri, NULL, NULL,
list->dlist[j].sock?list->dlist[j].sock:probing_sock,
&dlg) != 0 ) {
LM_ERR("failed to create new TM dlg\n");
continue;
/* build its pack, so we can build and send the prob later */
pack = shm_malloc(sizeof(struct gw_prob_pack) +
list->dlist[j].uri.len );
if( pack==0 ) {
LM_ERR("no more shm memory!\n");
/* send whatever probs we have so far */
break;
}
dlg->state = DLG_CONFIRMED;

if (ds_ping_maxfwd>=0) {
dlg->mf_enforced = 1;
dlg->mf_value = (unsigned short)ds_ping_maxfwd;
pack->uri.s = (char*)(pack+1);
memcpy(pack->uri.s, list->dlist[j].uri.s,
list->dlist[j].uri.len);
pack->uri.len = list->dlist[j].uri.len;

pack->sock = list->dlist[j].sock;

if (partition->attrs_avp_name>=0) {
val.s = list->dlist[j].attrs;
pack->avps = new_avp(
AVP_VAL_STR|partition->attrs_avp_type,
partition->attrs_avp_name, val);
// we do not care if the adding failed, there will
// be no attr AVP exposed in local route
if (pack->avps)
pack->avps->next = NULL;
} else
pack->avps = NULL;

pack->params.partition = partition;
pack->params.set_id = list->id;

if (pack_head==NULL) {
pack_head = pack_last = pack;
} else {
pack_last->next = pack;
pack_last = pack;
}

ds_options_callback_param_t *cb_param =
shm_malloc(sizeof(*cb_param));

if (cb_param == NULL) {
LM_CRIT("No more shared memory\n");
continue;
}
cb_param->partition = partition;
cb_param->set_id = list->id;
if (tmb.t_request_within(&ds_ping_method,
NULL,
NULL,
dlg,
ds_options_callback,
(void*)cb_param,
osips_shm_free) < 0) {
LM_ERR("unable to execute dialog\n");
shm_free(cb_param);
}
tmb.free_dlg(dlg);
}
}
}

lock_stop_read( partition->lock );

/* now send all the probs, outside the lock */
for( pack = pack_head ; pack ; pack=pack->next ) {

/* Execute the Dialog using the "request"-Method of the
* TM-Module.*/
if (tmb.new_auto_dlg_uac(&ds_ping_from,
&pack->uri, NULL, NULL,
pack->sock?pack->sock:probing_sock,
&dlg) != 0 ) {
LM_ERR("failed to create new TM dlg\n");
continue;
}
dlg->state = DLG_CONFIRMED;

if (ds_ping_maxfwd>=0) {
dlg->mf_enforced = 1;
dlg->mf_value = (unsigned short)ds_ping_maxfwd;
}
dlg->avps = pack->avps;
pack->avps = NULL;

if (tmb.t_request_within(&ds_ping_method,
NULL,
NULL,
dlg,
ds_options_callback,
(void*)pack,
osips_shm_free) < 0) {
LM_ERR("unable to execute dialog\n");
shm_free(pack);
}
tmb.free_dlg(dlg);

}
}
}

Expand Down

0 comments on commit 1461263

Please sign in to comment.