switch_mutex_unlock(tech_pvt->profile->flag_mutex);
sofia_glue_deactivate_rtp(tech_pvt);
+
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY) && !tech_pvt->profile->inuse) {
+ sofia_profile_destroy(tech_pvt->profile);
+ }
}
return SWITCH_STATUS_SUCCESS;
switch_call_cause_t cause = switch_channel_get_cause(channel);
int sip_cause = hangup_cause_to_sip(cause);
const char *ps_cause = NULL, *use_my_cause;
+
+ if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY)) {
+ return SWITCH_STATUS_SUCCESS;
+ }
switch_mutex_lock(tech_pvt->sofia_mutex);
PFLAG_PASS_CALLEE_ID,
PFLAG_LOG_AUTH_FAIL,
PFLAG_TRACK_CALLS,
+ PFLAG_DESTROY,
/* No new flags below this line */
PFLAG_MAX
} PFLAGS;
sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key);
#define sofia_glue_find_profile(x) sofia_glue_find_profile__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
+#define sofia_glue_profile_rdlock(x) sofia_glue_profile_rdlock__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
+switch_status_t sofia_glue_profile_rdlock__(const char *file, const char *func, int line, sofia_profile_t *profile);
+
switch_status_t sofia_reg_add_gateway(char *key, sofia_gateway_t *gateway);
sofia_gateway_t *sofia_reg_find_gateway__(const char *file, const char *func, int line, const char *key);
#define sofia_reg_find_gateway(x) sofia_reg_find_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event);
+#define sofia_reg_gateway_rdlock(x) sofia_reg_gateway_rdlock__(__FILE__, __SWITCH_FUNC__, __LINE__, x)
+switch_status_t sofia_reg_gateway_rdlock__(const char *file, const char *func, int line, sofia_gateway_t *gateway);
+
void sofia_reg_release_gateway__(const char *file, const char *func, int line, sofia_gateway_t *gateway);
#define sofia_reg_release_gateway(x) sofia_reg_release_gateway__(__FILE__, __SWITCH_FUNC__, __LINE__, x);
void sofia_glue_tech_untrack(sofia_profile_t *profile, switch_core_session_t *session, switch_bool_t force);
void sofia_glue_tech_track(sofia_profile_t *profile, switch_core_session_t *session);
int sofia_glue_recover(switch_bool_t flush);
+void sofia_profile_destroy(sofia_profile_t *profile);
int locked = 0;
int check_destroy = 1;
+ /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be
+ freed whenever the request is done */
if (nh && sofia_private == &mod_sofia_globals.keep_private) {
if (status >= 300) {
nua_handle_bind(nh, NULL);
return;
}
}
+
if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) {
if ((gateway = sofia_private->gateway)) {
- if (switch_thread_rwlock_tryrdlock(gateway->profile->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile %s is locked\n", gateway->profile->name);
+ /* Released in sofia_reg_release_gateway() */
+ if (sofia_reg_gateway_rdlock(gateway) != SWITCH_STATUS_SUCCESS) {
return;
}
} else if (!zstr(sofia_private->uuid)) {
}
}
}
-
+
+
if (sofia_test_pflag(profile, PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
sip_authorization_t const *authorization = NULL;
if (sofia_test_pflag(profile, PFLAG_RESPAWN)) {
config_sofia(1, profile->name);
}
-
- switch_core_destroy_memory_pool(&pool);
+
+ sofia_profile_destroy(profile);
end:
switch_mutex_lock(mod_sofia_globals.mutex);
return NULL;
}
+void sofia_profile_destroy(sofia_profile_t *profile)
+{
+ if (!profile->inuse) {
+ switch_memory_pool_t *pool = profile->pool;
+ switch_core_destroy_memory_pool(&pool);
+ } else {
+ sofia_set_pflag(profile, PFLAG_DESTROY);
+ }
+}
+
void launch_sofia_profile_thread(sofia_profile_t *profile)
{
switch_thread_t *thread;
return url;
}
+switch_status_t sofia_glue_profile_rdlock__(const char *file, const char *func, int line, sofia_profile_t *profile)
+{
+ switch_status_t status = switch_thread_rwlock_tryrdlock(profile->rwlock);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is locked\n", profile->name);
+ return status;
+ }
+#ifdef SOFIA_DEBUG_RWLOCKS
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX LOCK %s\n", profile->name);
+#endif
+ return status;
+}
+
sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key)
{
sofia_profile_t *profile;
profile = NULL;
goto done;
}
- if (switch_thread_rwlock_tryrdlock(profile->rwlock) != SWITCH_STATUS_SUCCESS) {
-#ifdef SOFIA_DEBUG_RWLOCKS
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is locked\n", profile->name);
-#endif
+ if (sofia_glue_profile_rdlock__(file, func, line, profile) != SWITCH_STATUS_SUCCESS) {
profile = NULL;
}
} else {
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is not in the hash\n", key);
#endif
}
-#ifdef SOFIA_DEBUG_RWLOCKS
- if (profile) {
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX LOCK %s\n", profile->name);
- }
-#endif
- done:
+done:
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
return profile;
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
gateway_ptr->retry = 0;
- if (!gateway_ptr->nh)
+ if (!gateway_ptr->nh) {
sofia_reg_new_handle(gateway_ptr, now ? 1 : 0);
+ }
if (sofia_glue_check_nat(gateway_ptr->profile, gateway_ptr->register_proxy)) {
user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport);
gateway = NULL;
goto done;
}
- if (switch_thread_rwlock_tryrdlock(gateway->profile->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is locked\n", gateway->profile->name);
+ if (sofia_reg_gateway_rdlock__(file, func, line, gateway) != SWITCH_STATUS_SUCCESS) {
gateway = NULL;
}
}
- if (gateway) {
-#ifdef SOFIA_DEBUG_RWLOCKS
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX GW LOCK %s\n", gateway->profile->name);
-#endif
- }
done:
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
return gateway;
}
+switch_status_t sofia_reg_gateway_rdlock__(const char *file, const char *func, int line, sofia_gateway_t *gateway)
+{
+ switch_status_t status = sofia_glue_profile_rdlock__(file, func, line, gateway->profile);
+
+#ifdef SOFIA_DEBUG_RWLOCKS
+ if (status != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX GW LOCK %s\n", gateway->profile->name);
+ }
+#endif
+
+ return status;
+}
+
void sofia_reg_release_gateway__(const char *file, const char *func, int line, sofia_gateway_t *gateway)
{