add mutex around gateway access on per-profile basis and token based access to global profiles to prevent hanging on to the hash mutex while doing sql stmts which may cause issues/slowdowns
This commit is contained in:
parent
dc61e08e5d
commit
9df8169d1f
|
@ -4940,7 +4940,7 @@ static void general_event_handler(switch_event_t *event)
|
|||
}
|
||||
}
|
||||
|
||||
static switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches)
|
||||
switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches)
|
||||
{
|
||||
sofia_profile_t *profile = NULL;
|
||||
switch_hash_index_t *hi;
|
||||
|
@ -4983,9 +4983,11 @@ static switch_status_t list_gateways(const char *line, const char *cursor, switc
|
|||
profile = (sofia_profile_t *) val;
|
||||
if (sofia_test_pflag(profile, PFLAG_RUNNING)) {
|
||||
sofia_gateway_t *gp;
|
||||
switch_mutex_lock(profile->gw_mutex);
|
||||
for (gp = profile->gateways; gp; gp = gp->next) {
|
||||
switch_console_push_match(&my_matches, gp->name);
|
||||
}
|
||||
switch_mutex_unlock(profile->gw_mutex);
|
||||
}
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
|
|
|
@ -592,6 +592,7 @@ struct sofia_profile {
|
|||
uint32_t step_timeout;
|
||||
uint32_t event_timeout;
|
||||
int watchdog_enabled;
|
||||
switch_mutex_t *gw_mutex;
|
||||
};
|
||||
|
||||
struct private_object {
|
||||
|
@ -1034,6 +1035,7 @@ switch_status_t sofia_set_loglevel(const char *name, int level);
|
|||
* \note Valid components are "default" (sofia's default logger), "tport", "iptsec", "nea", "nta", "nth_client", "nth_server", "nua", "soa", "sresolv", "stun"
|
||||
* \return the component's loglevel, or -1 if the component isn't valid
|
||||
*/
|
||||
switch_status_t list_profiles(const char *line, const char *cursor, switch_console_callback_match_t **matches);
|
||||
int sofia_get_loglevel(const char *name);
|
||||
sofia_cid_type_t sofia_cid_name2type(const char *name);
|
||||
void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_str, switch_bool_t dup);
|
||||
|
|
|
@ -3055,6 +3055,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
|||
goto done;
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_init(&profile->gw_mutex, SWITCH_MUTEX_NESTED, pool);
|
||||
|
||||
profile->trans_timeout = 100;
|
||||
|
||||
profile->auto_rtp_bugs = RTP_BUG_CISCO_SKIP_MARK_BIT_2833;// | RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833;
|
||||
|
|
|
@ -5518,27 +5518,21 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName
|
|||
|
||||
int sofia_glue_recover(switch_bool_t flush)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
sofia_profile_t *profile;
|
||||
char *sql;
|
||||
int r = 0;
|
||||
switch_console_callback_match_t *matches;
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
if (mod_sofia_globals.profile_hash) {
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
|
||||
if ((profile = (sofia_profile_t *) val)) {
|
||||
if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_callback_match_node_t *m;
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
if ((profile = sofia_glue_find_profile(m->val))) {
|
||||
|
||||
struct recover_helper h = { 0 };
|
||||
h.profile = profile;
|
||||
h.total = 0;
|
||||
|
||||
if (strcmp((char *) var, profile->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
sql = switch_mprintf("delete from sip_recovery where profile_name='%q'", profile->name);
|
||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||
|
@ -5559,8 +5553,8 @@ int sofia_glue_recover(switch_bool_t flush)
|
|||
}
|
||||
}
|
||||
}
|
||||
switch_console_free_matches(&matches);
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -275,33 +275,40 @@ void sofia_presence_cancel(void)
|
|||
{
|
||||
char *sql;
|
||||
sofia_profile_t *profile;
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
struct presence_helper helper = { 0 };
|
||||
switch_console_callback_match_t *matches;
|
||||
|
||||
if (!mod_sofia_globals.profile_hash)
|
||||
if (!mod_sofia_globals.profile_hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||
if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_callback_match_node_t *m;
|
||||
|
||||
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||
",-1,'unavailable','unavailable' from sip_subscriptions where version > -1 and "
|
||||
"expires > -1 and event='presence' and hostname='%q'",
|
||||
mod_sofia_globals.hostname))) {
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, NULL, NULL, &val);
|
||||
profile = (sofia_profile_t *) val;
|
||||
if (profile->pres_type != PRES_TYPE_FULL) {
|
||||
continue;
|
||||
}
|
||||
mod_sofia_globals.hostname);
|
||||
|
||||
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
if ((profile = sofia_glue_find_profile(m->val))) {
|
||||
if (profile->pres_type == PRES_TYPE_FULL) {
|
||||
helper.profile = profile;
|
||||
helper.event = NULL;
|
||||
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) {
|
||||
sofia_glue_release_profile(profile);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sofia_glue_release_profile(profile);
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(sql);
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
switch_console_free_matches(&matches);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,23 +404,29 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
|
|||
if (!profile) {
|
||||
if (!host || !(profile = sofia_glue_find_profile(host))) {
|
||||
char *sql;
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
const void *vvar;
|
||||
char buf[512] = "";
|
||||
switch_console_callback_match_t *matches;
|
||||
|
||||
sql = switch_mprintf("select profile_name from sip_registrations where sip_host='%s' or mwi_host='%s'", host, host);
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &vvar, NULL, &val);
|
||||
profile = (sofia_profile_t *) val;
|
||||
if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_callback_match_node_t *m;
|
||||
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
if ((profile = sofia_glue_find_profile(m->val))) {
|
||||
|
||||
sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
|
||||
if (!zstr(buf)) {
|
||||
break;
|
||||
}
|
||||
sofia_glue_release_profile(profile);
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
}
|
||||
|
||||
switch_console_free_matches(&matches);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(profile = sofia_glue_find_profile(buf))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile %s\n", switch_str_nil(host));
|
||||
|
@ -509,9 +522,6 @@ static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, cha
|
|||
static void actual_sofia_presence_event_handler(switch_event_t *event)
|
||||
{
|
||||
sofia_profile_t *profile = NULL;
|
||||
switch_hash_index_t *hi;
|
||||
const void *var;
|
||||
void *val;
|
||||
char *from = switch_event_get_header(event, "from");
|
||||
char *proto = switch_event_get_header(event, "proto");
|
||||
char *rpid = switch_event_get_header(event, "rpid");
|
||||
|
@ -524,7 +534,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||
char *call_info = switch_event_get_header(event, "presence-call-info");
|
||||
char *call_info_state = switch_event_get_header(event, "presence-call-info-state");
|
||||
struct resub_helper h = { 0 };
|
||||
|
||||
switch_console_callback_match_t *matches;
|
||||
|
||||
if (!mod_sofia_globals.running) {
|
||||
return;
|
||||
|
@ -581,28 +591,28 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||
}
|
||||
|
||||
switch_assert(sql != NULL);
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
profile = (sofia_profile_t *) val;
|
||||
|
||||
if (strcmp((char *) var, profile->name)) {
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is an alias, skipping\n", (char *) var);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_callback_match_node_t *m;
|
||||
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
if ((profile = sofia_glue_find_profile(m->val))) {
|
||||
if (profile->pres_type != PRES_TYPE_FULL) {
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) var);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
|
||||
}
|
||||
sofia_glue_release_profile(profile);
|
||||
continue;
|
||||
}
|
||||
helper.profile = profile;
|
||||
helper.event = NULL;
|
||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper);
|
||||
sofia_glue_release_profile(profile);
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
}
|
||||
switch_console_free_matches(&matches);
|
||||
}
|
||||
|
||||
free(sql);
|
||||
return;
|
||||
}
|
||||
|
@ -774,27 +784,22 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||
|
||||
|
||||
|
||||
if (!mod_sofia_globals.profile_hash)
|
||||
if (!mod_sofia_globals.profile_hash) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||
if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_console_callback_match_node_t *m;
|
||||
|
||||
for (m = matches->head; m; m = m->next) {
|
||||
struct dialog_helper dh = { { 0 } };
|
||||
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
profile = (sofia_profile_t *) val;
|
||||
|
||||
if (strcmp((char *) var, profile->name)) {
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is an alias, skipping\n", (char *) var);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((profile = sofia_glue_find_profile(m->val))) {
|
||||
if (profile->pres_type != PRES_TYPE_FULL) {
|
||||
if (mod_sofia_globals.debug_presence > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) var);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
|
||||
}
|
||||
sofia_glue_release_profile(profile);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -929,8 +934,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||
switch_safe_free(helper.stream.data);
|
||||
helper.stream.data = NULL;
|
||||
}
|
||||
sofia_glue_release_profile(profile);
|
||||
}
|
||||
}
|
||||
switch_console_free_matches(&matches);
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
|
||||
done:
|
||||
switch_safe_free(sql);
|
||||
|
|
|
@ -134,7 +134,7 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
|
|||
*/
|
||||
sofia_gateway_t *gateway_ptr;
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
switch_mutex_lock(profile->gw_mutex);
|
||||
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
|
||||
sofia_gateway_subscription_t *gw_sub_ptr;
|
||||
|
||||
|
@ -235,7 +235,7 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now)
|
|||
switch_safe_free(user_via);
|
||||
}
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
switch_mutex_unlock(profile->gw_mutex);
|
||||
}
|
||||
|
||||
void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
|
||||
|
@ -244,7 +244,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
|
|||
switch_event_t *event;
|
||||
char *pkey;
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
switch_mutex_lock(profile->gw_mutex);
|
||||
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
|
||||
if (gateway_ptr->deleted && gateway_ptr->state == REG_STATE_NOREG) {
|
||||
if (last) {
|
||||
|
@ -447,7 +447,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
|
|||
sofia_reg_fire_custom_gateway_state_event(gateway_ptr, 0, NULL);
|
||||
}
|
||||
}
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
switch_mutex_unlock(profile->gw_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2735,11 +2735,14 @@ switch_status_t sofia_reg_add_gateway(sofia_profile_t *profile, const char *key,
|
|||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
char *pkey = switch_mprintf("%s::%s", profile->name, key);
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
switch_mutex_lock(profile->gw_mutex);
|
||||
|
||||
gateway->next = profile->gateways;
|
||||
profile->gateways = gateway;
|
||||
|
||||
switch_mutex_unlock(profile->gw_mutex);
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
if (!switch_core_hash_find(mod_sofia_globals.gateway_hash, key)) {
|
||||
status = switch_core_hash_insert(mod_sofia_globals.gateway_hash, key, gateway);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue