Main Page | Modules | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

switch_core_state_machine.c File Reference


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)


Define Documentation

#define STATE_MACRO __STATE,
__STATE_STR   ) 
 


Function Documentation

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:

void switch_core_state_machine_init switch_memory_pool_t pool  ) 
 

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


Generated on Mon May 26 22:06:52 2008 for FreeSWITCH by  doxygen 1.3.9.1