]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
small core refactoring use -hp arg to gain high priority mode, add fsctl command...
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 20 Sep 2006 20:25:26 +0000 (20:25 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 20 Sep 2006 20:25:26 +0000 (20:25 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@2765 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/switch.c
src/switch_channel.c
src/switch_console.c
src/switch_core.c
src/switch_rtp.c

index e2947ae4db373f84ce510545068f08d9c9af5c2d..1ce8f616a9279ffd8371c82fe57e65ecceace5b3 100644 (file)
@@ -409,8 +409,9 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st
 
 /*! 
   \brief Hangup All Sessions
+  \param cause the hangup cause to apply to the hungup channels
 */
-SWITCH_DECLARE(void) switch_core_session_hupall(void);
+SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause);
 
 /*! 
   \brief Send a message to another session using it's uuid
@@ -1198,6 +1199,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_directory_close(switch_directory_han
 */
 SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel);
 
+
+/*! 
+  \brief Set the maximum priority the process can obtain
+  \return 0 on success
+*/
+SWITCH_DECLARE(int32_t) set_high_priority(void);
+
+/*! 
+  \brief Run endlessly until the system is shutdown
+  \param bg divert console to the background
+*/
+SWITCH_DECLARE(void) switch_core_runtime_loop(int bg);
+
 /*!
   \brief Set the output console to the desired file
   \param console the file path
@@ -1217,6 +1231,14 @@ SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_cor
 */
 SWITCH_DECLARE(switch_time_t) switch_core_uptime(void);
 
+/*!
+  \brief send a control message to the core
+  \param cmd the command
+  \param val the command arguement (if needed)
+  \return 0 on success nonzero on error
+*/
+SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, uint32_t *val);
+
 /*!
   \brief Get the output console
   \return the FILE stream
index 2e9191beb4b48278b969d5db6274282d66115bfa..3a7adc79f5fc971a3b97c7b1fd1b9e8834c58a0c 100644 (file)
@@ -176,6 +176,7 @@ typedef enum {
        SWITCH_RTP_FLAG_VAD           - Enable VAD
        SWITCH_RTP_FLAG_BREAK             - Stop what you are doing and return SWITCH_STATUS_BREAK
        SWITCH_RTP_FLAG_MINI              - Use mini RTP when possible
+       SWITCH_RTP_FLAG_DATAWAIT          - Do not return from reads unless there is data even when non blocking
 </pre>
  */
 typedef enum {
@@ -189,7 +190,8 @@ typedef enum {
        SWITCH_RTP_FLAG_GOOGLEHACK = (1 << 7),
        SWITCH_RTP_FLAG_VAD = (1 << 8),
        SWITCH_RTP_FLAG_BREAK = ( 1 << 9),
-       SWITCH_RTP_FLAG_MINI = ( 1 << 10)
+       SWITCH_RTP_FLAG_MINI = ( 1 << 10),
+       SWITCH_RTP_FLAG_DATAWAIT = (1 << 11)
 } switch_rtp_flag_t;
 
 /*!
@@ -690,9 +692,16 @@ typedef enum {
        SWITCH_CAUSE_INTERWORKING = 127,
        SWITCH_CAUSE_CRASH = 500,
        SWITCH_CAUSE_SYSTEM_SHUTDOWN = 501,
-       SWITCH_CAUSE_LOSE_RACE = 502
+       SWITCH_CAUSE_LOSE_RACE = 502,
+       SWITCH_CAUSE_MANAGER_REQUEST = 503
 } switch_call_cause_t;
 
+typedef enum {
+       SCSC_PAUSE_INBOUND,
+       SCSC_HUPALL,
+       SCSC_SHUTDOWN,
+       SCSC_CHECK_RUNNING
+} switch_session_ctl_t;
 
 typedef uint8_t switch_payload_t;
 typedef struct switch_rtp switch_rtp_t;
index ad1a0ecd23b126d6171ed8b7e47bf67b73f450e9..453fedb087e9fd02494894208585f9bf2fac94f3 100644 (file)
@@ -87,6 +87,49 @@ static switch_status_t status_function(char *cmd, switch_core_session_t *session
        return SWITCH_STATUS_SUCCESS;
 }
 
+static switch_status_t ctl_function(char *data, switch_core_session_t *session, switch_stream_handle_t *stream)
+{
+       int argc;
+       char *mydata, *argv[5];
+       uint32_t arg = 0;
+
+       if (switch_strlen_zero(data)) {
+               stream->write_function(stream, "USAGE: fsctl [hupall|pause|resume|shutdown]\n");
+               return SWITCH_STATUS_SUCCESS;
+       }
+
+       if ((mydata = strdup(data))) {
+               argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+       
+               if (!strcmp(argv[0], "hupall")) {
+                       arg = 1;
+                       switch_core_session_ctl(SCSC_HUPALL, &arg);
+               } else if (!strcmp(argv[0], "pause")) {
+                       arg = 1;
+                       switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg);
+               } else if (!strcmp(argv[0], "resume")) {
+                       arg = 0;
+                       switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg);
+               } else if (!strcmp(argv[0], "shutdown")) {
+                       arg = 0;
+                       switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
+               } else {
+                       stream->write_function(stream, "INVALID COMMAND [%s]\n", argv[0]);
+                       goto end;
+               } 
+
+               stream->write_function(stream, "OK\n");
+       end:
+               free(mydata);
+       } else {
+               stream->write_function(stream, "MEM ERR\n");
+       }
+
+    return SWITCH_STATUS_SUCCESS;
+       
+}
+
+
 static switch_status_t load_function(char *mod, switch_core_session_t *session, switch_stream_handle_t *stream)
 {
 
@@ -436,11 +479,18 @@ static switch_status_t show_function(char *cmd, switch_core_session_t *session,
 
 
 
+static switch_api_interface_t ctl_api_interface = {
+       /*.interface_name */ "fsctl",
+       /*.desc */ "control messages",
+       /*.function */ ctl_function,
+       /*.next */ 
+};
+
 static switch_api_interface_t uuid_bridge_api_interface = {
        /*.interface_name */ "uuid_bridge",
        /*.desc */ "uuid_bridge",
        /*.function */ uuid_bridge_function,
-       /*.next */ NULL
+       /*.next */ &ctl_api_interface
 };
 
 static switch_api_interface_t status_api_interface = {
index 374836158627d69f3ef43af341f004936a45788b..914e87e57edb83294bbb5f97b98bb4602cc4fc42 100644 (file)
@@ -727,7 +727,7 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt)
        bw = tech_pvt->read_codec.implementation->bits_per_second;
        ms = tech_pvt->read_codec.implementation->microseconds_per_frame;
 
-       flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_RAW_WRITE | SWITCH_RTP_FLAG_MINI | SWITCH_RTP_FLAG_AUTOADJ);
+       flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_RAW_WRITE | SWITCH_RTP_FLAG_MINI | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT);
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
                                          switch_channel_get_name(channel),
@@ -812,6 +812,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
        size_t bytes = 0, samples = 0, frames = 0, ms = 0;
        switch_channel_t *channel = NULL;
        int payload = 0;
+
        //switch_time_t now, started = switch_time_now(), last_act = switch_time_now();
        //unsigned int elapsed;
        //uint32_t hard_timeout = 60000 * 3;
@@ -903,8 +904,6 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
                                tech_pvt->read_frame.samples = (int) samples;
                                break;
                        }
-
-                       switch_yield(1000);
                }
 
        } 
index 154ad497262fe29719d813b087fd84e2c99faa0b..12774532021aa5a05517267ff243677ae355ef6c 100644 (file)
@@ -35,7 +35,7 @@
 
 #define PIDFILE "freeswitch.pid"
 #define LOGFILE "freeswitch.log"
-static int RUNNING = 0;
+
 static char *lfile = LOGFILE;
 static char *pfile = PIDFILE;
 #define SERVICENAME "Freeswitch"
@@ -53,37 +53,12 @@ static HANDLE shutdown_event;
 
        static int handle_SIGHUP(int sig)
 {
+       uint32_t arg = 0;
        if(sig);
-       RUNNING = 0;
+       switch_core_session_ctl(SCSC_SHUTDOWN, &arg);
        return 0;
 }
 
-static void set_high_priority()
-{
-#ifdef WIN32
-       SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
-#else
-       //nice(-19);
-#endif
-}
-
-static void freeswitch_runtime_loop(int bg)
-{
-       if (bg) {
-               bg = 0;
-#ifdef WIN32
-               WaitForSingleObject(shutdown_event, INFINITE);
-#else
-               RUNNING = 1;
-               while(RUNNING) {
-                       switch_yield(10000);
-               }
-#endif
-       }  else {
-               /* wait for console input */
-               switch_console_loop();
-       }
-}
 
 static int freeswitch_kill_background()
 {
@@ -175,6 +150,7 @@ int main(int argc, char *argv[])
        int bg = 0;
        FILE *f;
        pid_t pid = 0;
+       int x, die = 0;
 
 #ifdef WIN32
     SERVICE_TABLE_ENTRY dispatchTable[] =
@@ -182,60 +158,71 @@ int main(int argc, char *argv[])
         { SERVICENAME, &service_main },
         { NULL, NULL }
     };
+#endif
 
-       if (argv[1] && !strcmp(argv[1], "-service")) {
-               if(StartServiceCtrlDispatcher( dispatchTable ) == 0 )
-               {
-                       //Not loaded as a service
-                       fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
-                       fprintf(stderr, "To install the service load freeswitch with -install\n");
-               }
-               exit(0);
-       }
-       if (argv[1] && !strcmp(argv[1], "-install")) {
-               char exePath[1024];
-           char servicePath[1024];
-
-               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
-               GetModuleFileName( NULL, exePath, 1024 );
-               snprintf(servicePath, sizeof(servicePath), "%s -service", exePath);
-               CreateService(
-                       handle,
-                       SERVICENAME,
-                       SERVICENAME,
-                       GENERIC_READ | GENERIC_EXECUTE,
-                       SERVICE_WIN32_OWN_PROCESS,
-                       SERVICE_AUTO_START,
-                       SERVICE_ERROR_IGNORE,
-                       servicePath,
-                       NULL,
-                       NULL,
-                       NULL,
-                       NULL,
-                       NULL
-               );
-               exit(0);
-       }
-       if (argv[1] && !strcmp(argv[1], "-uninstall")) {
-               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
-               SC_HANDLE service = OpenService( handle, SERVICENAME, DELETE );
-               if( service != NULL )
-               {
-                       // remove the service!
-                       DeleteService( service );
+       for (x = 1; x < argc; x++) {
+#ifdef WIN32
+               if (x == 1) {
+                       if (argv[x] && !strcmp(argv[x], "-service")) {
+                               if(StartServiceCtrlDispatcher( dispatchTable ) == 0 )
+                                       {
+                                               //Not loaded as a service
+                                               fprintf(stderr, "Error Freeswitch loaded as a console app with -service option\n");
+                                               fprintf(stderr, "To install the service load freeswitch with -install\n");
+                                       }
+                               exit(0);
+                       }
+                       if (argv[x] && !strcmp(argv[x], "-install")) {
+                               char exePath[1024];
+                               char servicePath[1024];
+
+                               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+                               GetModuleFileName( NULL, exePath, 1024 );
+                               snprintf(servicePath, sizeof(servicePath), "%s -service", exePath);
+                               CreateService(
+                                                         handle,
+                                                         SERVICENAME,
+                                                         SERVICENAME,
+                                                         GENERIC_READ | GENERIC_EXECUTE,
+                                                         SERVICE_WIN32_OWN_PROCESS,
+                                                         SERVICE_AUTO_START,
+                                                         SERVICE_ERROR_IGNORE,
+                                                         servicePath,
+                                                         NULL,
+                                                         NULL,
+                                                         NULL,
+                                                         NULL,
+                                                         NULL
+                                                         );
+                               exit(0);
+                       }
+                       if (argv[x] && !strcmp(argv[x], "-uninstall")) {
+                               SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+                               SC_HANDLE service = OpenService( handle, SERVICENAME, DELETE );
+                               if( service != NULL )
+                                       {
+                                               // remove the service!
+                                               DeleteService( service );
+                                       }
+                               exit(0);
+                       }
                }
-               exit(0);
-       }
 #endif
+               if (argv[x] && !strcmp(argv[x], "-hp")) {
+                       set_high_priority();
+               }
+               
+               if (argv[x] && !strcmp(argv[x], "-stop")) {
+                       die++;
+               }
 
-       set_high_priority();
-
-       if (argv[1] && !strcmp(argv[1], "-stop")) {
-               return freeswitch_kill_background();
+               if (argv[x] && !strcmp(argv[x], "-nc")) {
+                       bg++;
+               }
        }
 
-       if (argv[1] && !strcmp(argv[1], "-nc")) {
-               bg++;
+       if (die) {
+               return freeswitch_kill_background();
        }
 
        if (bg) {
@@ -270,7 +257,7 @@ int main(int argc, char *argv[])
        fprintf(f, "%d", pid = getpid());
        fclose(f);
 
-       freeswitch_runtime_loop(bg);
+       switch_core_runtime_loop(bg);
 
        return switch_core_destroy();
 }
index a74484ed9387ff972c85bc8cc82aafdce71a9746..b608598dfb4ab630d487463aa3b452822cb5ad63 100644 (file)
@@ -86,6 +86,7 @@ static struct switch_cause_table CAUSE_CHART[] = {
        { "CRASH", SWITCH_CAUSE_CRASH },
        { "SYSTEM_SHUTDOWN", SWITCH_CAUSE_SYSTEM_SHUTDOWN },
        { "LOSE_RACE", SWITCH_CAUSE_LOSE_RACE },
+       { "MANAGER_REQUEST", SWITCH_CAUSE_MANAGER_REQUEST },
        { NULL, 0 }
 };
 
index 26e6a13b713632b9c50a782509777ab44b6f94f4..9bf49c0b4cfa2e568a7f1bbd1a319d100b142a33 100644 (file)
@@ -203,20 +203,33 @@ SWITCH_DECLARE(void) switch_console_loop(void)
 {
        char hostname[256];
        char cmd[2048];
-       int running = 1, activity = 1;
+       uint32_t activity = 1, running = 1;
        switch_size_t x = 0;
 
        gethostname(hostname, sizeof(hostname));
 
-       while (running) {
+       while(running) {
+               uint32_t arg;
+               fd_set rfds, efds;
+               struct timeval tv = {0, 20000};
+
+               switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg);
+               if (!arg) {
+                       break;
+               }
+
                if (activity) {
                        switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", hostname);
                }
-               //activity = switch_socket_waitfor(fileno(stdin), 100, POLLIN | POLLERR);
+               
+               FD_ZERO(&rfds);
+               FD_ZERO(&efds);
+               FD_SET(fileno(stdin), &rfds);
+               FD_SET(fileno(stdin), &efds);
+               activity = select(fileno(stdin)+1, &rfds, NULL, &efds, &tv);
 
                if (activity == 0) {
                        fflush(stdout);
-                       switch_sleep(100);
                        continue;
                }
 
index 0028e774a4ed62d6969988a248a411a165a8bccc..e3d9780e83374c4cd023bc1f63cf73417c92a082 100644 (file)
@@ -127,6 +127,9 @@ struct switch_core_runtime {
        uint32_t session_count;
        uint32_t session_limit;
        switch_queue_t *sql_queue;
+       uint32_t no_new_sessions;
+       uint32_t shutting_down;
+       uint8_t running;
 };
 
 /* Prototypes */
@@ -536,7 +539,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(char *uuid_st
        }
 }
 
-SWITCH_DECLARE(void) switch_core_session_hupall(void)
+SWITCH_DECLARE(void) switch_core_session_hupall(switch_call_cause_t cause)
 {
        switch_hash_index_t *hi;
        void *val;
@@ -549,7 +552,7 @@ SWITCH_DECLARE(void) switch_core_session_hupall(void)
                if (val) {
                        session = (switch_core_session_t *) val;
                        channel = switch_core_session_get_channel(session);
-                       switch_channel_hangup(channel, SWITCH_CAUSE_SYSTEM_SHUTDOWN);
+                       switch_channel_hangup(channel, cause);
                }
        }
        switch_mutex_unlock(runtime.session_table_mutex);
@@ -3111,6 +3114,11 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request(const switch
                return NULL;
        }
 
+       if (runtime.no_new_sessions || runtime.shutting_down) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read my lips: no new sessions!\n");
+               return NULL;
+       }
+
        if (pool) {
                usepool = pool;
        } else if (switch_core_new_memory_pool(&usepool) != SWITCH_STATUS_SUCCESS) {
@@ -3474,6 +3482,55 @@ SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
        return runtime.session_limit;
 }
 
+
+SWITCH_DECLARE(int32_t) set_high_priority(void)
+{
+#ifdef __linux__
+       struct sched_param sched = {0};
+       sched.sched_priority = 1;
+       if (sched_setscheduler(0, SCHED_RR, &sched)) {
+        sched.sched_priority = 0;
+        if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
+                       return -1;
+               }
+       }
+#endif
+
+#ifdef WIN32
+       SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+#else
+       nice(-10);
+#endif
+
+#define USE_MLOCKALL
+#ifdef HAVE_MLOCKALL
+#ifdef USE_MLOCKALL
+       mlockall(MCL_CURRENT|MCL_FUTURE);
+#endif
+#endif
+       return 0;
+}
+
+
+SWITCH_DECLARE(void) switch_core_runtime_loop(int bg)
+{
+       if (bg) {
+               bg = 0;
+#ifdef WIN32
+               WaitForSingleObject(shutdown_event, INFINITE);
+#else
+               runtime.running = 1;
+               while(runtime.running) {
+                       switch_yield(1000000);
+               }
+#endif
+       }  else {
+               /* wait for console input */
+               switch_console_loop();
+       }
+}
+
+
 SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err)
 {
        switch_xml_t xml = NULL, cfg = NULL;
@@ -3602,7 +3659,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(char *console, const char **err
        }
 
        runtime.session_id = 1;
-
+       runtime.running = 1;
        switch_core_hash_init(&runtime.session_table, runtime.memory_pool);
        switch_mutex_init(&runtime.session_table_mutex, SWITCH_MUTEX_NESTED, runtime.memory_pool);
 #ifdef CRASH_PROT
@@ -3662,13 +3719,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(char *console, cons
                switch_event_fire(&event);
        }
 
-//#define USE_MLOCKALL
-#ifdef HAVE_MLOCKALL
-#ifdef USE_MLOCKALL
-       mlockall(MCL_CURRENT|MCL_FUTURE);
-#endif
-#endif
-
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nFreeSWITCH Version %s Started.\nCrash Protection [%s]\nMax Sessions[%u]\n\n", SWITCH_VERSION_FULL, __CP, switch_core_session_limit(0));
        return SWITCH_STATUS_SUCCESS;
 
@@ -3696,6 +3746,31 @@ SWITCH_DECLARE(switch_time_t) switch_core_uptime(void)
        return switch_time_now() - runtime.initiated;
 }
 
+SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, uint32_t *val)
+{
+
+       if (runtime.shutting_down) {
+               return -1;
+       }
+
+       switch (cmd) {
+       case SCSC_PAUSE_INBOUND:
+               runtime.no_new_sessions = *val;
+               break;
+       case SCSC_HUPALL:
+               switch_core_session_hupall(SWITCH_CAUSE_MANAGER_REQUEST);
+               break;
+       case SCSC_SHUTDOWN:
+               runtime.running = 0;
+               break;
+       case SCSC_CHECK_RUNNING:
+               *val = runtime.running;
+               break;
+       }
+
+       return 0;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
 {
        switch_event_t *event;
@@ -3703,9 +3778,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Event-Info", "System Shutting Down");
                switch_event_fire(&event);
        }
+       runtime.shutting_down = 1;
+       runtime.no_new_sessions = 1;
 
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "End existing sessions\n");
-       switch_core_session_hupall();
+       switch_core_session_hupall(SWITCH_CAUSE_SYSTEM_SHUTDOWN);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clean up modules.\n");
        switch_loadable_module_shutdown();
 
index 338125042ef747d1ca418994d199f5c4e6d1165e..e54c81321d771fffee650008ab22aedfd0b9bf65 100644 (file)
@@ -841,6 +841,10 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
                }               
                
                if (status == SWITCH_STATUS_BREAK || bytes == 0) {
+                       if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DATAWAIT)) {
+                               switch_yield(rtp_session->ms_per_packet);
+                               continue;
+                       }
                        return 0;
                }