mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-17 17:22:21 +00:00
remove removal while traversing the hash and and lock to elimate race FS-3432
This commit is contained in:
parent
78641d4264
commit
2be25c6a56
@ -356,18 +356,16 @@ session_elem_t *find_session_elem_by_pid(listener_t *listener, erlang_pid *pid)
|
|||||||
void *val = NULL;
|
void *val = NULL;
|
||||||
session_elem_t *session = NULL;
|
session_elem_t *session = NULL;
|
||||||
|
|
||||||
switch_thread_rwlock_rdlock(listener->session_rwlock);
|
|
||||||
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
||||||
switch_hash_this(iter, &key, NULL, &val);
|
switch_hash_this(iter, &key, NULL, &val);
|
||||||
session = (session_elem_t*)val;
|
|
||||||
if (session->process.type == ERLANG_PID && !ei_compare_pids(pid, &session->process.pid)) {
|
if (((session_elem_t*)val)->process.type == ERLANG_PID && !ei_compare_pids(pid, &((session_elem_t*)val)->process.pid)) {
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
session = (session_elem_t*)val;
|
||||||
return session;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
|
||||||
|
|
||||||
return NULL;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -779,6 +777,9 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
|
|||||||
session_elem_t *s;
|
session_elem_t *s;
|
||||||
|
|
||||||
remove_binding(NULL, pid); /* TODO - why don't we pass the listener as the first argument? */
|
remove_binding(NULL, pid); /* TODO - why don't we pass the listener as the first argument? */
|
||||||
|
|
||||||
|
/* TODO - eliminate session destroy races and we shouldn't lock the session hash */
|
||||||
|
switch_thread_rwlock_wrlock(listener->session_rwlock);
|
||||||
if ((s = find_session_elem_by_pid(listener, pid))) {
|
if ((s = find_session_elem_by_pid(listener, pid))) {
|
||||||
if (s->channel_state < CS_HANGUP) {
|
if (s->channel_state < CS_HANGUP) {
|
||||||
switch_core_session_t *session;
|
switch_core_session_t *session;
|
||||||
@ -794,9 +795,12 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
|
|||||||
/* TODO - if a spawned process that was handling an outbound call fails.. what do we do with the call? */
|
/* TODO - if a spawned process that was handling an outbound call fails.. what do we do with the call? */
|
||||||
/* TODO hangup and let the state handler set the complete flag and destroy as usual*/
|
/* TODO hangup and let the state handler set the complete flag and destroy as usual*/
|
||||||
}
|
}
|
||||||
remove_session_elem_from_listener_locked(listener, s);
|
if (remove_session_elem_from_listener(listener, s) == SWITCH_STATUS_SUCCESS) {
|
||||||
destroy_session_elem(s);
|
destroy_session_elem(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
switch_thread_rwlock_wrlock(listener->session_rwlock);
|
||||||
|
|
||||||
|
|
||||||
if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) {
|
if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) {
|
||||||
void *pop;
|
void *pop;
|
||||||
@ -1255,7 +1259,6 @@ void destroy_listener(listener_t * listener)
|
|||||||
switch_hash_this(iter, &key, NULL, &value);
|
switch_hash_this(iter, &key, NULL, &value);
|
||||||
s = (session_elem_t*)value;
|
s = (session_elem_t*)value;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Orphaning call %s\n", s->uuid_str);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Orphaning call %s\n", s->uuid_str);
|
||||||
remove_session_elem_from_listener(listener, s);
|
|
||||||
destroy_session_elem(s);
|
destroy_session_elem(s);
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
switch_thread_rwlock_unlock(listener->session_rwlock);
|
||||||
@ -1275,6 +1278,7 @@ static switch_status_t state_handler(switch_core_session_t *session)
|
|||||||
session_elem_t *session_element = switch_channel_get_private(channel, "_erlang_session_");
|
session_elem_t *session_element = switch_channel_get_private(channel, "_erlang_session_");
|
||||||
/*listener_t* listener = switch_channel_get_private(channel, "_erlang_listener_"); */
|
/*listener_t* listener = switch_channel_get_private(channel, "_erlang_listener_"); */
|
||||||
|
|
||||||
|
/* TODO make thread safe */
|
||||||
if (session_element) {
|
if (session_element) {
|
||||||
session_element->channel_state = state;
|
session_element->channel_state = state;
|
||||||
if (state == CS_DESTROY) {
|
if (state == CS_DESTROY) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user