]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add -ncwait for Unix based implememtations to make the backgrounder wait to make...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 29 Oct 2010 17:43:55 +0000 (12:43 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 29 Oct 2010 17:43:55 +0000 (12:43 -0500)
src/switch.c

index a28baba6f076028fb243430a56d3becbade48b6b..5c2cba3c63314c92224f14d7ed6752ff2ff39b93 100644 (file)
@@ -50,7 +50,7 @@
 /* pid filename: Stores the process id of the freeswitch process */
 #define PIDFILE "freeswitch.pid"
 static char *pfile = PIDFILE;
-
+static int system_ready = 0;
 
 /* Picky compiler */
 #ifdef __ICC
@@ -82,6 +82,31 @@ static void handle_SIGILL(int sig)
        return;
 }
 
+static void handle_SIGUSR2(int sig)
+{
+       if (sig);
+
+       system_ready = 1;
+
+       return;
+}
+
+static void handle_SIGCHLD(int sig)
+{
+       int status = 0;
+       int pid = 0;
+
+       if (sig);
+
+       pid = wait(&status);
+       
+       if (pid > 0) {
+               system_ready = -1;
+       }
+
+       return;
+}
+
 /* kill a freeswitch process running in background mode */
 static int freeswitch_kill_background()
 {
@@ -209,27 +234,31 @@ void WINAPI service_main(DWORD numArgs, char **args)
 
 #else
 
-void daemonize(void)
+void daemonize(int do_wait)
 {
        int fd;
        pid_t pid;
 
-       switch (fork()) {
-       case 0:
-               break;
-       case -1:
-               fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
-               exit(0);
-               break;
-       default:
-               exit(0);
-       }
+       if (!do_wait) {
+               switch (fork()) {
+               case 0:
+                       break;
+               case -1:
+                       fprintf(stderr, "Error Backgrounding (fork)! %d - %s\n", errno, strerror(errno));
+                       exit(0);
+                       break;
+               default:
+                       exit(0);
+               }
 
-       if (setsid() < 0) {
-               fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno));
-               exit(0);
+               if (setsid() < 0) {
+                       fprintf(stderr, "Error Backgrounding (setsid)! %d - %s\n", errno, strerror(errno));
+                       exit(0);
+               }
        }
+
        pid = fork();
+
        switch (pid) {
        case 0:
                break;
@@ -238,10 +267,39 @@ void daemonize(void)
                exit(0);
                break;
        default:
-               fprintf(stderr, "%d Backgrounding.\n", (int) pid);
+               {
+                       fprintf(stderr, "%d Backgrounding.\n", (int) pid);
+
+
+                       if (do_wait) {
+                               unsigned int sanity = 20;
+                               while(--sanity && !system_ready) {
+                               
+                                       if (sanity % 2 == 0) {
+                                               printf("FreeSWITCH[%d] Waiting for background process pid:%d to be ready.....\n", getpid(), (int) pid);
+                                       }
+                                       sleep(1);
+                               }
+
+                               if (system_ready == 1) {
+                                       printf("FreeSWITCH[%d] System Ready pid:%d\n", (int) getpid(), (int) pid);
+                               } else {
+                                       printf("FreeSWITCH[%d] Error starting system! pid:%d\n", (int)getpid(), (int) pid);
+                                       kill(pid, 9);
+                                       exit(-1);
+                               }
+                       
+                       }
+
+               }
+
                exit(0);
        }
 
+       if (do_wait) {
+               setsid();
+       }
+
        /* redirect std* to null */
        fd = open("/dev/null", O_RDONLY);
        if (fd != 0) {
@@ -286,9 +344,10 @@ int main(int argc, char *argv[])
        int local_argc = argc;
        char *arg_argv[128] = { 0 };
        char *usageDesc;
-       int alt_dirs = 0, log_set = 0, run_set = 0, kill = 0;
+       int alt_dirs = 0, log_set = 0, run_set = 0, do_kill = 0;
        int known_opt;
        int high_prio = 0;
+       int do_wait = 0;
 #ifdef __sun
        switch_core_flag_t flags = SCF_USE_SQL;
 #else
@@ -343,6 +402,9 @@ int main(int argc, char *argv[])
                "\t-nort                  -- disable clock clock_realtime\n"
                "\t-stop                  -- stop freeswitch\n"
                "\t-nc                    -- do not output to a console and background\n"
+#ifndef WIN32
+               "\t-ncwait                -- do not output to a console and background but wait until the system is ready before exiting (implies -nc)\n"
+#endif
                "\t-c                     -- output to a console and stay in the foreground\n"
                "\t-conf [confdir]        -- specify an alternate config dir\n"
                "\t-log [logdir]          -- specify an alternate log dir\n"
@@ -518,7 +580,7 @@ int main(int argc, char *argv[])
                }
 
                if (local_argv[x] && !strcmp(local_argv[x], "-stop")) {
-                       kill++;
+                       do_kill++;
                        known_opt++;
                }
 
@@ -526,7 +588,13 @@ int main(int argc, char *argv[])
                        nc++;
                        known_opt++;
                }
-
+#ifndef WIN32
+               if (local_argv[x] && !strcmp(local_argv[x], "-ncwait")) {
+                       nc++;
+                       do_wait++;
+                       known_opt++;
+               }
+#endif
                if (local_argv[x] && !strcmp(local_argv[x], "-c")) {
                        nc = 0;
                        known_opt++;
@@ -664,7 +732,7 @@ int main(int argc, char *argv[])
                strcpy(SWITCH_GLOBAL_dirs.run_dir, SWITCH_GLOBAL_dirs.log_dir);
        }
 
-       if (kill) {
+       if (do_kill) {
                return freeswitch_kill_background();
        }
 
@@ -678,41 +746,33 @@ int main(int argc, char *argv[])
                return 255;
        }
 
-       signal(SIGILL, handle_SIGILL);
-       signal(SIGTERM, handle_SIGILL);
 
-       if (nc) {
-#ifdef WIN32
-               FreeConsole();
-#else
-               if (!nf) {
-                       daemonize();
-               }
-#endif
-       }
 #if defined(HAVE_SETRLIMIT) && !defined(__sun)
        if (!waste && !(flags & SCF_VG)) {
+               int x;
+
                memset(&rlp, 0, sizeof(rlp));
-               getrlimit(RLIMIT_STACK, &rlp);
+               x = getrlimit(RLIMIT_STACK, &rlp);
+
                if (rlp.rlim_max > SWITCH_THREAD_STACKSIZE) {
                        char buf[1024] = "";
                        int i = 0;
 
                        fprintf(stderr, "Error: stacksize %d is too large: run ulimit -s %d or run %s -waste.\nauto-adjusting stack size for optimal performance...\n",
                                        (int) (rlp.rlim_max / 1024), SWITCH_THREAD_STACKSIZE / 1024, local_argv[0]);
-
+                       
                        memset(&rlp, 0, sizeof(rlp));
                        rlp.rlim_cur = SWITCH_THREAD_STACKSIZE;
                        rlp.rlim_max = SWITCH_THREAD_STACKSIZE;
                        setrlimit(RLIMIT_STACK, &rlp);
-
+                       
                        apr_terminate();
                        ret = (int) execv(argv[0], argv);
-
+                       
                        for (i = 0; i < argc; i++) {
                                switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s ", argv[i]);
                        }
-
+                       
                        return system(buf);
 
                }
@@ -720,6 +780,25 @@ int main(int argc, char *argv[])
 #endif
 
 
+       signal(SIGILL, handle_SIGILL);
+       signal(SIGTERM, handle_SIGILL);
+#ifndef WIN32
+       if (do_wait) {
+               signal(SIGUSR2, handle_SIGUSR2);
+               signal(SIGCHLD, handle_SIGCHLD);
+       }
+#endif
+       
+       if (nc) {
+#ifdef WIN32
+               FreeConsole();
+#else
+               if (!nf) {
+                       daemonize(do_wait);
+               }
+#endif
+       }
+
 
 
        if (high_prio) {
@@ -800,6 +879,12 @@ int main(int argc, char *argv[])
                return 255;
        }
 
+#ifndef WIN32
+       if (do_wait) {
+               kill(getppid(), SIGUSR2);
+       }
+#endif
+
        switch_core_runtime_loop(nc);
 
        destroy_status = switch_core_destroy();