From 9df8169d1f3458e0b565a64922a1390ebf324703 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Jun 2011 14:32:08 -0500 Subject: [PATCH] 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 --- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 3 + src/mod/endpoints/mod_sofia/sofia_glue.c | 20 +- src/mod/endpoints/mod_sofia/sofia_presence.c | 388 ++++++++++--------- src/mod/endpoints/mod_sofia/sofia_reg.c | 13 +- 6 files changed, 221 insertions(+), 209 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b06eacb36d..a7e6d99dc2 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -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); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index b996167074..db8a6ff9e3 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -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); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index d9a2a3af0d..bf9ff4e7c4 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -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; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 15abe43dc3..6fcf2e30cd 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -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; } diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index a7490f6a8b..2ca69c5f57 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -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 (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); + - if ((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; - } - helper.profile = profile; - helper.event = NULL; - if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper) != SWITCH_TRUE) { - continue; + 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; - sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf)); - if (!zstr(buf)) { - break; + 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_console_free_matches(&matches); } - switch_mutex_unlock(mod_sofia_globals.hash_mutex); + + 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; @@ -548,7 +558,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) if (event->event_id == SWITCH_EVENT_ROSTER) { struct presence_helper helper = { 0 }; - + if (!mod_sofia_globals.profile_hash) 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 (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) { + switch_console_callback_match_node_t *m; - 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); + 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 *) 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); } - continue; } - 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); - } - continue; - } - helper.profile = profile; - helper.event = NULL; - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_callback, &helper); + switch_console_free_matches(&matches); } - switch_mutex_unlock(mod_sofia_globals.hash_mutex); + free(sql); return; } @@ -774,163 +784,161 @@ 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)) { - struct dialog_helper dh = { { 0 } }; + if (list_profiles(NULL, NULL, &matches) == SWITCH_STATUS_SUCCESS) { + switch_console_callback_match_node_t *m; - switch_hash_this(hi, &var, NULL, &val); - profile = (sofia_profile_t *) val; + for (m = matches->head; m; m = m->next) { + struct dialog_helper dh = { { 0 } }; - 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->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); - } - continue; - } - - if (call_info) { - const char *uuid = switch_event_get_header(event, "unique-id"); + 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 *) profile->name); + } + sofia_glue_release_profile(profile); + continue; + } + if (call_info) { + const char *uuid = switch_event_get_header(event, "unique-id"); + #if 0 - if (mod_sofia_globals.debug_sla > 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SLA EVENT:\n"); - DUMP_EVENT(event); - } + if (mod_sofia_globals.debug_sla > 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SLA EVENT:\n"); + DUMP_EVENT(event); + } #endif - if (uuid) { - sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' where hostname='%q' and uuid='%q'", - call_info, call_info_state, mod_sofia_globals.hostname, uuid); - } else { - sql = switch_mprintf("update sip_dialogs set call_info='%q', call_info_state='%q' where hostname='%q' and " - "((sip_dialogs.sip_from_user='%q' and sip_dialogs.sip_from_host='%q') or presence_id='%q@%q') and call_info='%q'", - - call_info, call_info_state, mod_sofia_globals.hostname, euser, host, euser, host, call_info); - - } - - if (mod_sofia_globals.debug_sla > 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql); - } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + if (uuid) { + sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' where hostname='%q' and uuid='%q'", + call_info, call_info_state, mod_sofia_globals.hostname, uuid); + } else { + sql = switch_mprintf("update sip_dialogs set call_info='%q', call_info_state='%q' where hostname='%q' and " + "((sip_dialogs.sip_from_user='%q' and sip_dialogs.sip_from_host='%q') or presence_id='%q@%q') and call_info='%q'", + + call_info, call_info_state, mod_sofia_globals.hostname, euser, host, euser, host, call_info); + + } + + if (mod_sofia_globals.debug_sla > 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql); + } + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + - - if (mod_sofia_globals.debug_sla > 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n"); - } - - sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE); - } - - if (!strcmp(proto, "dp")) { - sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where sip_user='%q' and sip_host='%q'", - rpid, status, euser, host); - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - } - - sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", - euser, host, euser, host); - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); - switch_safe_free(sql); - - if ((sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," - "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," - "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," - "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," - "sip_subscriptions.accept,sip_subscriptions.profile_name" - ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q'," - "sip_subscriptions.version, '%q' " - "from sip_subscriptions " - "left join sip_presence on " - "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " - "sip_subscriptions.profile_name=sip_presence.profile_name) " - - "where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and " - "(event='%q' or event='%q') and sub_to_user='%q' " - "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " - "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ", - - switch_str_nil(status), switch_str_nil(rpid), host, - dh.status,dh.rpid,dh.presence_id, - event_type, alt_event_type, euser, host, host, profile->name))) { - - struct presence_helper helper = { 0 }; - - helper.profile = profile; - helper.event = event; - SWITCH_STANDARD_STREAM(helper.stream); - switch_assert(helper.stream.data); - - if (mod_sofia_globals.debug_presence > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n", - event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); - } - - if (mod_sofia_globals.debug_presence) { - char *buf; - switch_event_serialize(event, &buf, SWITCH_FALSE); - switch_assert(buf); - if (mod_sofia_globals.debug_presence > 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DUMP PRESENCE SQL:\n%s\nEVENT DUMP:\n%s\n", sql, buf); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "EVENT DUMP:\n%s\n", buf); + if (mod_sofia_globals.debug_sla > 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n"); + } + + sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE); } - free(buf); - } + + if (!strcmp(proto, "dp")) { + sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where sip_user='%q' and sip_host='%q'", + rpid, status, euser, host); + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + } + + sql = switch_mprintf("select status,rpid,presence_id from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q')", + euser, host, euser, host); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_dialog_callback, &dh); + switch_safe_free(sql); + + if ((sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host," + "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event," + "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from," + "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent," + "sip_subscriptions.accept,sip_subscriptions.profile_name" + ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q'," + "sip_subscriptions.version, '%q' " + "from sip_subscriptions " + "left join sip_presence on " + "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and " + "sip_subscriptions.profile_name=sip_presence.profile_name) " + + "where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and " + "(event='%q' or event='%q') and sub_to_user='%q' " + "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " + "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ", + + switch_str_nil(status), switch_str_nil(rpid), host, + dh.status,dh.rpid,dh.presence_id, + event_type, alt_event_type, euser, host, host, profile->name))) { + + struct presence_helper helper = { 0 }; - sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_presence_sub_callback, &helper); - switch_safe_free(sql); - - sql = switch_mprintf("update sip_subscriptions set version=version+1 where event='dialog' and sub_to_user='%q' " - "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " - "and (profile_name = '%q' or presence_hosts != sub_to_host)", - euser, host, host, profile->name); + helper.profile = profile; + helper.event = event; + SWITCH_STANDARD_STREAM(helper.stream); + switch_assert(helper.stream.data); + + if (mod_sofia_globals.debug_presence > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n", + event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); + } - sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); - - - if (mod_sofia_globals.debug_presence > 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n", - event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); - } - - if (!zstr((char *) helper.stream.data)) { - char *this_sql = (char *) helper.stream.data; - char *next = NULL; - char *last = NULL; - - do { - if ((next = strchr(this_sql, ';'))) { - *next++ = '\0'; - while (*next == '\n' || *next == ' ' || *next == '\r') { - *next++ = '\0'; + if (mod_sofia_globals.debug_presence) { + char *buf; + switch_event_serialize(event, &buf, SWITCH_FALSE); + switch_assert(buf); + if (mod_sofia_globals.debug_presence > 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DUMP PRESENCE SQL:\n%s\nEVENT DUMP:\n%s\n", sql, buf); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "EVENT DUMP:\n%s\n", buf); } + free(buf); } - if (!zstr(this_sql) && (!last || strcmp(last, this_sql))) { - sofia_glue_execute_sql(profile, &this_sql, SWITCH_FALSE); - last = this_sql; + sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_presence_sub_callback, &helper); + switch_safe_free(sql); + + sql = switch_mprintf("update sip_subscriptions set version=version+1 where event='dialog' and sub_to_user='%q' " + "and (sub_to_host='%q' or presence_hosts like '%%%q%%') " + "and (profile_name = '%q' or presence_hosts != sub_to_host)", + euser, host, host, profile->name); + + sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); + + + if (mod_sofia_globals.debug_presence > 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n", + event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name); } - this_sql = next; - } while (this_sql); + + if (!zstr((char *) helper.stream.data)) { + char *this_sql = (char *) helper.stream.data; + char *next = NULL; + char *last = NULL; + + do { + if ((next = strchr(this_sql, ';'))) { + *next++ = '\0'; + while (*next == '\n' || *next == ' ' || *next == '\r') { + *next++ = '\0'; + } + } + + if (!zstr(this_sql) && (!last || strcmp(last, this_sql))) { + sofia_glue_execute_sql(profile, &this_sql, SWITCH_FALSE); + last = this_sql; + } + this_sql = next; + } while (this_sql); + } + switch_safe_free(helper.stream.data); + helper.stream.data = NULL; + } + sofia_glue_release_profile(profile); } - switch_safe_free(helper.stream.data); - helper.stream.data = NULL; } + switch_console_free_matches(&matches); } - switch_mutex_unlock(mod_sofia_globals.hash_mutex); done: switch_safe_free(sql); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index df02436ecd..730576f949 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -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); }