]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add threaded-system-exec param and fsctl (set it to false to use fork)
authorAnthony Minessale <anthm@freeswitch.org>
Mon, 12 Sep 2011 19:24:58 +0000 (14:24 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Mon, 12 Sep 2011 19:25:01 +0000 (14:25 -0500)
configure.in
src/include/switch_types.h
src/mod/applications/mod_commands/mod_commands.c
src/switch.c
src/switch_core.c

index 6a7d7dec4df00e45a620ca3443274fa323ff99ad..b74e973a4ac508027716dd6ad1471d49bd106ed4 100644 (file)
@@ -474,7 +474,7 @@ AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MALLOC
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
-AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create])
+AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize])
 AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
 AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
 
index 51ed3587e5adb4f0f53a384c60a920f8e09acbc9..97fbc942af0096201fa8718ac4b932a7bfc6be49 100644 (file)
@@ -306,7 +306,8 @@ typedef enum {
        SCF_AUTO_SCHEMAS = (1 << 13),
        SCF_MINIMAL = (1 << 14),
        SCF_USE_NAT_MAPPING = (1 << 15),
-       SCF_CLEAR_SQL = (1 << 16)
+       SCF_CLEAR_SQL = (1 << 16),
+       SCF_THREADED_SYSTEM_EXEC = (1 << 17)
 } switch_core_flag_enum_t;
 typedef uint32_t switch_core_flag_t;
 
@@ -1677,7 +1678,8 @@ typedef enum {
        SCSC_VERBOSE_EVENTS,
        SCSC_SHUTDOWN_CHECK,
        SCSC_PAUSE_CHECK,
-       SCSC_READY_CHECK
+       SCSC_READY_CHECK,
+       SCSC_THREADED_SYSTEM_EXEC
 } switch_session_ctl_t;
 
 typedef enum {
index dba27031b1bd90920254eede88dfc7cca33c4b1c..a5175299be78f141a7a8a98c5cfd38f6302f90ef 100644 (file)
@@ -1840,6 +1840,15 @@ SWITCH_STANDARD_API(ctl_function)
                        switch_core_session_ctl(SCSC_VERBOSE_EVENTS, &arg);
 
                        stream->write_function(stream, "+OK verbose_events is %s \n", arg ? "on" : "off");
+               } else if (!strcasecmp(argv[0], "threaded_system_exec")) {
+                       arg = -1;
+                       if (argv[1]) {
+                               arg = switch_true(argv[1]);
+                       }
+
+                       switch_core_session_ctl(SCSC_THREADED_SYSTEM_EXEC, &arg);
+
+                       stream->write_function(stream, "+OK threaded_system_exec is %s \n", arg ? "true" : "false");
                        
                } else if (!strcasecmp(argv[0], "save_history")) {
                        switch_core_session_ctl(SCSC_SAVE_HISTORY, NULL);
index 401829cf829cfbf6c073eabd07c7671e7782e792..4ef38111f2ebe9a88bfbcf56261176322d131fb0 100644 (file)
@@ -102,6 +102,7 @@ static void handle_SIGCHLD(int sig)
        pid = wait(&status);
        
        if (pid > 0) {
+               printf("ASS %d\n", pid);
                system_ready = -1;
        }
 
index e9e5b3871c0e623514dfd412d11f0a062c6fe493..ba0350a7fe8e03880566e56f73b0d1bcb8bc6a8f 100644 (file)
@@ -647,6 +647,41 @@ SWITCH_DECLARE(void) switch_core_set_globals(void)
        switch_assert(SWITCH_GLOBAL_dirs.temp_dir);
 }
 
+
+static int32_t set_low_priority(void)
+{
+#ifdef WIN32
+       SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
+#else
+#ifdef USE_SCHED_SETSCHEDULER
+       /*
+        * Try to use a normal scheduler
+        */
+       struct sched_param sched = { 0 };
+       sched.sched_priority = 0;
+       if (sched_setscheduler(0, SCHED_OTHER, &sched)) {
+               return -1;
+       }
+#endif
+
+#ifdef HAVE_SETPRIORITY
+       /*
+        * setpriority() works on FreeBSD (6.2), nice() doesn't
+        */
+       if (setpriority(PRIO_PROCESS, getpid(), 19) < 0) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#else
+       if (nice(19) != 19) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not set nice level\n");
+               return -1;
+       }
+#endif
+#endif
+       return 0;
+}
+
 static int32_t set_priority(void)
 {
 #ifdef WIN32
@@ -1359,6 +1394,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
        switch_set_flag((&runtime.dummy_cng_frame), SFF_CNG);
        switch_set_flag((&runtime), SCF_AUTO_SCHEMAS);
        switch_set_flag((&runtime), SCF_CLEAR_SQL);
+       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
 
        switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
        runtime.hard_log_level = SWITCH_LOG_DEBUG;
@@ -1483,6 +1519,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
 }
 
 
+#ifndef WIN32
+static void handle_SIGCHLD(int sig)
+{
+       int status = 0;
+       int pid = 0;
+
+       if (sig);
+
+       pid = wait(&status);
+       
+       if (pid > 0) {
+               printf("ASS %d\n", pid);
+       }
+
+       return;
+}
+#endif
+
 #ifdef TRAP_BUS
 static void handle_SIGBUS(int sig)
 {
@@ -1690,6 +1744,17 @@ static void switch_load_core_config(const char *file)
                                        } else {
                                                switch_clear_flag((&runtime), SCF_VERBOSE_EVENTS);
                                        }
+                               } else if (!strcasecmp(var, "threaded-system-exec") && !zstr(val)) {
+#ifdef WIN32
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "threaded-system-exec is not implemented on this platform\n");
+#else
+                                       int v = switch_true(val);
+                                       if (v) {
+                                               switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                                       } else {
+                                               switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                                       }
+#endif
                                } else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
                                        switch_core_min_idle_cpu(atof(val));
                                } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
@@ -1870,7 +1935,9 @@ SWITCH_DECLARE(void) switch_core_set_signal_handlers(void)
 {
        /* set signal handlers */
        signal(SIGINT, SIG_IGN);
-
+#ifndef WIN32
+       signal(SIGCHLD, handle_SIGCHLD);
+#endif
 #ifdef SIGPIPE
        signal(SIGPIPE, SIG_IGN);
 #endif
@@ -1924,6 +1991,18 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *
                        newintval = switch_test_flag((&runtime), SCF_VERBOSE_EVENTS);
                }
                break;
+       case SCSC_THREADED_SYSTEM_EXEC:
+               if (intval) {
+                       if (oldintval > -1) {
+                               if (oldintval) {
+                                       switch_set_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                               } else {
+                                       switch_clear_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+                               }
+                       }
+                       newintval = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC);
+               }
+               break;
        case SCSC_CALIBRATE_CLOCK:
                switch_time_calibrate_clock();
                break;
@@ -2256,7 +2335,8 @@ static void *SWITCH_THREAD_FUNC system_thread(switch_thread_t *thread, void *obj
        return NULL;
 }
 
-SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
+
+static int switch_system_thread(const char *cmd, switch_bool_t wait)
 {
        switch_thread_t *thread;
        switch_threadattr_t *thd_attr;
@@ -2296,6 +2376,68 @@ SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
 }
 
 
+#ifdef WIN32
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+       return switch_system_thread(cmd, wait);
+}
+
+#else
+static int max_open(void)
+{
+       int max;
+
+#if defined(HAVE_GETDTABLESIZE)
+       max = getdtablesize();
+#else
+       max = sysconf(_SC_OPEN_MAX);
+#endif
+
+       return max;
+
+}
+
+static int switch_system_fork(const char *cmd, switch_bool_t wait)
+{
+       int pid;
+
+       switch_core_set_signal_handlers();
+
+       pid = fork();
+       
+       if (pid) {
+               if (wait) {
+                       waitpid(pid, NULL, 0);
+               }
+       } else {
+               int open_max = max_open();
+               int i;
+
+               for (i = 3; i < open_max; i++) {
+                       close(i);
+               }
+               
+               set_low_priority();
+               system(cmd);
+               exit(0);
+       }
+
+       return 0;
+}
+#endif
+
+
+
+SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
+{
+       int (*sys_p)(const char *cmd, switch_bool_t wait);
+
+       sys_p = switch_test_flag((&runtime), SCF_THREADED_SYSTEM_EXEC) ? switch_system_thread : switch_system_fork;
+
+       return sys_p(cmd, wait);
+
+}
+
 
 /* For Emacs:
  * Local Variables: