SSF_NONE = 0,
SSF_DESTROYED = (1 << 0),
SSF_WARN_TRANSCODE = (1 << 1),
- SSF_HANGUP = (1 << 2)
+ SSF_HANGUP = (1 << 2),
+ SSF_THREAD_STARTED = (1 << 3),
+ SSF_THREAD_RUNNING = (1 << 4)
} switch_session_flag_t;
switch_endpoint_interface_t *endpoint_interface;
switch_size_t id;
switch_session_flag_t flags;
- int thread_running;
switch_channel_t *channel;
switch_io_event_hooks_t event_hooks;
\param session the session on which to check
*/
SWITCH_DECLARE(unsigned int) switch_core_session_running(_In_ switch_core_session_t *session);
+SWITCH_DECLARE(unsigned int) switch_core_session_started(_In_ switch_core_session_t *session);
SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(_In_ switch_size_t memory, _In_z_ const char *file, _In_z_ const char *func, _In_ int line);
{NULL, 0}
};
+typedef enum {
+ OCF_HANGUP = (1 << 0)
+} opaque_channel_flag_t;
+
struct switch_channel {
char *name;
switch_call_direction_t direction;
int vi;
int event_count;
int profile_index;
+ opaque_channel_flag_t opaque_flags;
};
SWITCH_DECLARE(const char *) switch_channel_cause2str(switch_call_cause_t cause)
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_channel_t *channel,
const char *file, const char *func, int line, switch_call_cause_t hangup_cause)
{
+ int ok = 0;
+
switch_assert(channel != NULL);
+ /* one per customer */
+ switch_mutex_lock(channel->state_mutex);
+ if (!(channel->opaque_flags & OCF_HANGUP)) {
+ channel->opaque_flags |= OCF_HANGUP;
+ ok = 1;
+ }
+ switch_mutex_unlock(channel->state_mutex);
+
+ if (!ok) {
+ return channel->state;
+ }
+
switch_channel_clear_flag(channel, CF_BLOCK_STATE);
if (channel->state < CS_HANGUP) {
switch_channel_state_t last_state;
switch_event_t *event;
- if (hangup_cause == SWITCH_CAUSE_LOSE_RACE) {
- switch_channel_set_variable(channel, "presence_call_info", NULL);
- }
-
switch_mutex_lock(channel->state_mutex);
last_state = channel->state;
channel->state = CS_HANGUP;
switch_mutex_unlock(channel->state_mutex);
+
+ if (hangup_cause == SWITCH_CAUSE_LOSE_RACE) {
+ switch_channel_set_variable(channel, "presence_call_info", NULL);
+ }
+
channel->hangup_cause = hangup_cause;
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Hangup %s [%s] [%s]\n",
channel->name, state_names[last_state], switch_channel_cause2str(channel->hangup_cause));
- if (!switch_core_session_running(channel->session)) {
+ if (!switch_core_session_running(channel->session) && !switch_core_session_started(channel->session)) {
switch_core_session_thread_launch(channel->session);
}
SWITCH_DECLARE(unsigned int) switch_core_session_running(switch_core_session_t *session)
{
- return session->thread_running;
+ return switch_test_flag(session, SSF_THREAD_RUNNING) ? 1 : 0;
+}
+
+SWITCH_DECLARE(unsigned int) switch_core_session_started(switch_core_session_t *session)
+{
+ return switch_test_flag(session, SSF_THREAD_STARTED) ? 1 : 0;
}
SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t **session, const char *file, const char *func, int line)
switch_mutex_lock(session->mutex);
- if (!session->thread_running) {
- session->thread_running = 1;
+ if (switch_test_flag(session, SSF_THREAD_RUNNING)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
+ } else if (switch_test_flag(session, SSF_THREAD_STARTED)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n");
+ } else {
+ switch_set_flag(session, SSF_THREAD_RUNNING);
+ switch_set_flag(session, SSF_THREAD_STARTED);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
if (switch_thread_create(&thread, thd_attr, switch_core_session_thread, session, session->pool) == SWITCH_STATUS_SUCCESS) {
+ switch_set_flag(session, SSF_THREAD_STARTED);
status = SWITCH_STATUS_SUCCESS;
} else {
- session->thread_running = 0;
+ switch_clear_flag(session, SSF_THREAD_RUNNING);
+ switch_clear_flag(session, SSF_THREAD_STARTED);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot create thread!\n");
}
- } else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot double-launch thread!\n");
}
switch_mutex_unlock(session->mutex);
*/
switch_assert(session != NULL);
- session->thread_running = 1;
+ switch_set_flag(session, SSF_THREAD_RUNNING);
endpoint_interface = session->endpoint_interface;
switch_assert(endpoint_interface != NULL);
done:
switch_mutex_unlock(session->mutex);
- session->thread_running = 0;
+ switch_clear_flag(session, SSF_THREAD_RUNNING);
}
SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session)
switch_channel_clear_flag(session->channel, CF_TRANSFER);
switch_channel_clear_flag(session->channel, CF_REDIRECT);
- session->thread_running = 1;
endpoint_interface = session->endpoint_interface;
switch_assert(endpoint_interface != NULL);
switch_assert(session != NULL);
- session->thread_running = 1;
endpoint_interface = session->endpoint_interface;
switch_assert(endpoint_interface != NULL);