Defines | |
| #define | STATE_MACRO(__STATE, __STATE_STR) |
Functions | |
| void | switch_core_state_machine_init (switch_memory_pool_t *pool) |
| void | switch_core_session_run (switch_core_session_t *session) |
|
|
|
|
|
00296 {
00297 switch_channel_state_t state = CS_NEW, midstate = CS_DONE, endstate;
00298 const switch_endpoint_interface_t *endpoint_interface;
00299 const switch_state_handler_table_t *driver_state_handler = NULL;
00300 const switch_state_handler_table_t *application_state_handler = NULL;
00301 switch_thread_id_t thread_id;
00302 jmp_buf env;
00303 int sig, silly = 0;
00304
00305 if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
00306 thread_id = switch_thread_self();
00307 signal(SIGSEGV, handle_fatality);
00308 signal(SIGFPE, handle_fatality);
00309 #ifndef WIN32
00310 signal(SIGBUS, handle_fatality);
00311 #endif
00312
00313 if ((sig = setjmp(env)) != 0) {
00314 switch_event_t *event;
00315
00316 if (switch_event_create(&event, SWITCH_EVENT_SESSION_CRASH) == SWITCH_STATUS_SUCCESS) {
00317 switch_channel_event_set_data(session->channel, event);
00318 switch_event_fire(&event);
00319 }
00320 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread has crashed for channel %s\n", switch_channel_get_name(session->channel));
00321 switch_channel_hangup(session->channel, SWITCH_CAUSE_CRASH);
00322 } else {
00323 sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), (void *)&env);
00324 //apr_hash_set(stack_table, &thread_id, sizeof(thread_id), &env);
00325 }
00326 }
00327
00328 /*
00329 Life of the channel. you have channel and pool in your session
00330 everywhere you go you use the session to malloc with
00331 switch_core_session_alloc(session, <size>)
00332
00333 The enpoint module gets the first crack at implementing the state
00334 if it wants to, it can cancel the default behaviour by returning SWITCH_STATUS_FALSE
00335
00336 Next comes the channel's event handler table that can be set by an application
00337 which also can veto the next behaviour in line by returning SWITCH_STATUS_FALSE
00338
00339 Finally the default state behaviour is called.
00340
00341
00342 */
00343 switch_assert(session != NULL);
00344
00345 session->thread_running = 1;
00346 endpoint_interface = session->endpoint_interface;
00347 switch_assert(endpoint_interface != NULL);
00348
00349 driver_state_handler = endpoint_interface->state_handler;
00350 switch_assert(driver_state_handler != NULL);
00351
00352 switch_mutex_lock(session->mutex);
00353
00354 while ((state = switch_channel_get_state(session->channel)) != CS_DONE) {
00355 uint8_t exception = 0;
00356 midstate = state;
00357 if (switch_channel_test_flag(session->channel, CF_REPEAT_STATE)) {
00358 switch_channel_clear_flag(session->channel, CF_REPEAT_STATE);
00359 exception = 1;
00360 }
00361 if (state != switch_channel_get_running_state(session->channel) || state == CS_HANGUP || exception) {
00362 int index = 0;
00363 int proceed = 1;
00364 int do_extra_handlers = 1;
00365
00366 switch_channel_set_running_state(session->channel, state);
00367
00368 switch (state) {
00369 case CS_NEW: /* Just created, Waiting for first instructions */
00370 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) State NEW\n", switch_channel_get_name(session->channel));
00371 break;
00372 case CS_DONE:
00373 goto done;
00374 /* HANGUP INIT ROUTING and RESET are all short term so we signal lock during their callbacks */
00375 case CS_HANGUP: /* Deactivate and end the thread */
00376 {
00377 const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
00378 const char *hook_var;
00379
00380 if (!switch_strlen_zero(var)) {
00381 if (!strcasecmp(var, "a_only")) {
00382 if (switch_channel_get_originator_caller_profile(session->channel)) {
00383 do_extra_handlers = 0;
00384 }
00385 } else if (!strcasecmp(var, "b_only")) {
00386 if (switch_channel_get_originatee_caller_profile(session->channel)) {
00387 do_extra_handlers = 0;
00388 }
00389 } else if (!switch_true(var)) {
00390 do_extra_handlers = 0;
00391 }
00392 }
00393 switch_core_session_signal_lock(session);
00394 STATE_MACRO(hangup, "HANGUP");
00395 switch_core_session_signal_unlock(session);
00396
00397 hook_var = switch_channel_get_variable(session->channel, SWITCH_API_HANGUP_HOOK_VARIABLE);
00398
00399 if (!switch_strlen_zero(hook_var)) {
00400 switch_stream_handle_t stream = { 0 };
00401 char *cmd = switch_core_session_strdup(session, hook_var);
00402 char *arg = NULL;
00403 if ((arg = strchr(cmd, ' '))) {
00404 *arg++ = '\0';
00405 }
00406 SWITCH_STANDARD_STREAM(stream);
00407 switch_api_execute(cmd, arg, NULL, &stream);
00408 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hangup Command %s(%s):\n%s\n", cmd, arg, switch_str_nil((char *) stream.data));
00409 switch_safe_free(stream.data);
00410 }
00411 }
00412 goto done;
00413 case CS_INIT: /* Basic setup tasks */
00414 switch_core_session_signal_lock(session);
00415 STATE_MACRO(init, "INIT");
00416 switch_core_session_signal_unlock(session);
00417 break;
00418 case CS_ROUTING: /* Look for a dialplan and find something to do */
00419 switch_core_session_signal_lock(session);
00420 STATE_MACRO(routing, "ROUTING");
00421 switch_core_session_signal_unlock(session);
00422 break;
00423 case CS_RESET: /* Reset */
00424 switch_core_session_signal_lock(session);
00425 STATE_MACRO(reset, "RESET");
00426 switch_core_session_signal_unlock(session);
00427 break;
00428 /* These other states are intended for prolonged durations so we do not signal lock for them */
00429 case CS_EXECUTE: /* Execute an Operation */
00430 STATE_MACRO(execute, "EXECUTE");
00431 break;
00432 case CS_EXCHANGE_MEDIA: /* loop all data back to source */
00433 STATE_MACRO(exchange_media, "EXCHANGE_MEDIA");
00434 break;
00435 case CS_SOFT_EXECUTE: /* send/recieve data to/from another channel */
00436 STATE_MACRO(soft_execute, "SOFT_EXECUTE");
00437 break;
00438 case CS_PARK: /* wait in limbo */
00439 STATE_MACRO(park, "PARK");
00440 break;
00441 case CS_CONSUME_MEDIA: /* wait in limbo */
00442 STATE_MACRO(consume_media, "CONSUME_MEDIA");
00443 break;
00444 case CS_HIBERNATE: /* sleep */
00445 STATE_MACRO(hibernate, "HIBERNATE");
00446 break;
00447 case CS_NONE:
00448 abort();
00449 break;
00450 }
00451
00452 if (midstate == CS_DONE) {
00453 break;
00454 }
00455
00456 }
00457
00458 endstate = switch_channel_get_state(session->channel);
00459
00460 if (endstate == switch_channel_get_running_state(session->channel)) {
00461 if (endstate == CS_NEW) {
00462 switch_yield(1000);
00463 } else {
00464 switch_thread_cond_wait(session->cond, session->mutex);
00465 }
00466 }
00467 }
00468 done:
00469 switch_mutex_unlock(session->mutex);
00470
00471 if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
00472 sqlite3HashInsert(&stack_table, &thread_id, sizeof(thread_id), NULL);
00473 //apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL);
00474 }
00475 session->thread_running = 0;
00476 }
|
Here is the call graph for this function:

|
|
00251 {
00252
00253 if (switch_test_flag((&runtime), SCF_CRASH_PROT)) {
00254 sqlite3HashInit(&stack_table, SQLITE_HASH_BINARY, 0);
00255 }
00256 }
|
1.3.9.1