- Modules can properly register processes in SER process table
authorJan Janak <jan@iptel.org>
Tue, 13 Dec 2005 12:10:15 +0000 (12:10 +0000)
committerJan Janak <jan@iptel.org>
Tue, 13 Dec 2005 12:10:15 +0000 (12:10 +0000)
  - process_count function has been replaced by process_count variable
  - modules can increase the value of process_count in mod_init,
    this will be used to allocate process table that will be big enough
  - modules can create processes in child_init with rank PROC_MAIN
    - the index into process table is in last_process, this is where
      information about the new process should be recorded
  - do not forget to reset is_main in the new process otherwise it
    will not be terminated properly
  - modules should increate last_process before fork
  - the new child should set process_no = last_process

core_cmd.c
fifo_server.c
main.c
modules/tm/t_stats.c
pt.h
tcp_main.c
unixsock_server.c

index 86e8dff..180671d 100644 (file)
@@ -159,7 +159,7 @@ static void core_ps(rpc_t* rpc, void* c)
 {
        int p;
 
-       for (p=0; p<process_count();p++) {
+       for (p=0; p<process_count;p++) {
                rpc->printf(c, "pid: %d", pt[p].pid);
                rpc->printf(c, "desc: %s", pt[p].desc);
        }
index 9bb67c5..baedf34 100644 (file)
@@ -864,7 +864,7 @@ static int ps_fifo_cmd(FILE *stream, char *response_file )
        }
 
        fputs( "200 ok\n", reply_pipe);
-       for (p=0; p<process_count();p++) 
+       for (p=0; p<process_count;p++) 
                fprintf( reply_pipe, "%d\t%d\t%s\n",
                        p, pt[p].pid, pt[p].desc );
 
diff --git a/main.c b/main.c
index 2966de1..a4135ac 100644 (file)
--- a/main.c
+++ b/main.c
@@ -335,6 +335,15 @@ struct host_alias* aliases=0; /* name aliases list */
 
 /* ipc related globals */
 int process_no = 0;
+
+/* Last filled entry in process table before calling
+ * child_init of loaded modules
+ */
+int last_process = 0;
+
+/* Total number of SER processes with given configuration */
+int process_count = 0;
+
 /* process_bm_t process_bit = 0; */
 #ifdef ROUTE_SRV
 #endif
@@ -421,7 +430,7 @@ static void kill_all_children(int signum)
 
        if (own_pgid) kill(0, signum);
        else if (pt)
-               for (r=1; r<process_count(); r++)
+               for (r=1; r<process_count; r++)
                        if (pt[r].pid) kill(pt[r].pid, signum);
 }
 
@@ -1010,7 +1019,7 @@ int main_loop()
                                         * parent gets a chance to set it*/
                                        pt[process_no].pid=getpid();
                                        bind_address=si; /* shortcut */
-                                       if (init_child(i + 1) < 0) {
+                                       if (init_child(process_no) < 0) {
                                                LOG(L_ERR, "init_child failed\n");
                                                goto error;
                                        }
@@ -1174,18 +1183,11 @@ int main_loop()
        }
 #endif
        /*DEBUG- remove it*/
-#ifdef EXTRA_DEBUG
-       fprintf(stderr, "\n% 3d processes (%3d), % 3d children * "
-                       "listening addresses + tcp listeners + tls listeners"
-                       "+ main + fifo + timer"
-# ifdef USE_SLOW_TIMER
-                       " + slow_timer"
-# endif
-                       "\n", process_no+1, process_count(), children_no);
-       for (r=0; r<=process_no; r++){
-               fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
-       }
-#endif
+
+       /* Modules need to know the last value of process_no to fill in
+        * process table properly
+        */
+       last_process = process_no;
        process_no=0; 
        /* process_bit = 0; */
        is_main=1;
@@ -1194,6 +1196,14 @@ int main_loop()
                LOG(L_ERR, "main: error in init_child\n");
                goto error;
        }
+
+       /*DEBUG- remove it*/
+#ifdef EXTRA_DEBUG
+       for (r=0; r<process_count; r++){
+               fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
+       }
+#endif
+
        for(;;){
                        pause();
                        handle_sigs();
@@ -1210,6 +1220,34 @@ int main_loop()
 }
 
 
+/*
+ * Calculate number of processes, this does not
+ * include processes created by modules
+ */
+static int calc_proc_no(void)
+{
+       int udp_listeners;
+       struct socket_info* si;
+       
+       for (si=udp_listen, udp_listeners=0; si; si=si->next, udp_listeners++);
+       return
+                    /* receivers and attendant */
+               (dont_fork ? 1 : children_no * udp_listeners + 1)
+                    /* timer process */
+               + 1 /* always, we need it in most cases, and we can't tell here
+                      & now if we don't need it */
+#ifdef USE_SLOW_TIMER
+               + 1 /* slow timer process */
+#endif
+               /* fifo server */
+               +((fifo==NULL || strlen(fifo)==0) ? 0 : 1 )
+               /* unixsock server*/
+               +(unixsock_name?unixsock_children:0)
+#ifdef USE_TCP
+               +((!tcp_disable)?( 1/* tcp main */ + tcp_children_no ):0) 
+#endif
+               ;
+}
 
 
 int main(int argc, char** argv)
@@ -1575,19 +1613,6 @@ try_again:
                fprintf(stderr, "ERROR: could not install the signal handlers\n");
                goto error;
        }
-       
-       
-       /*alloc pids*/
-#ifdef SHM_MEM
-       pt=shm_malloc(sizeof(struct process_table)*process_count());
-#else
-       pt=pkg_malloc(sizeof(struct process_table)*process_count());
-#endif
-       if (pt==0){
-               fprintf(stderr, "ERROR: out  of memory\n");
-               goto error;
-       }
-       memset(pt, 0, sizeof(struct process_table)*process_count());
 
        if (disable_core_dump) set_core_dump(0, 0);
        else set_core_dump(1, shm_mem_size+PKG_MEM_POOL_SIZE+4*1024*1024);
@@ -1597,11 +1622,34 @@ try_again:
                        goto error;
                }
        }
-       
+
+
+            /* Calculate initial process count, mod_init functions called 
+             * below can add to it
+             */
+       process_count = calc_proc_no(); 
        if (init_modules() != 0) {
                fprintf(stderr, "ERROR: error while initializing modules\n");
                goto error;
        }
+            /* The total number of processes is know now, note that no 
+             * function being called before this point may rely on the 
+             * number of processes !
+             */
+       DBG("Expect %d SER processes in your process list\n", process_count);
+
+       /*alloc pids*/
+#ifdef SHM_MEM
+       pt=shm_malloc(sizeof(struct process_table)*process_count);
+#else
+       pt=pkg_malloc(sizeof(struct process_table)*process_count);
+#endif
+       if (pt==0){
+               fprintf(stderr, "ERROR: out  of memory\n");
+               goto error;
+       }
+       memset(pt, 0, sizeof(struct process_table)*process_count);
+
        /* fix routing lists */
        if ( (r=fix_rls())!=0){
                fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
index 9688cd6..b7b964e 100644 (file)
@@ -57,7 +57,7 @@ int print_stats(  FILE *f )
        int i;
        int pno;
 
-       pno=process_count();
+       pno=process_count;
        for(i=0, total=0, waiting=0, total_local=0; i<pno;i++) {
                total+=tm_stats->s_transactions[i];
                waiting+=tm_stats->s_waiting[i];
@@ -119,7 +119,7 @@ int static unixsock_stats(str* cmd)
 
        unixsock_reply_asciiz( "200 OK\n");
 
-       pno = process_count();
+       pno = process_count;
        for(i = 0, total = 0, waiting = 0, total_local = 0; i < pno; i++) {
                total += tm_stats->s_transactions[i];
                waiting += tm_stats->s_waiting[i];
@@ -167,7 +167,7 @@ int init_tm_stats(void)
        }
        memset(tm_stats, 0, sizeof(struct t_stats) );
 
-       size=sizeof(stat_counter)*process_count();
+       size=sizeof(stat_counter)*process_count;
        tm_stats->s_waiting=shm_malloc(size);
        if (tm_stats->s_waiting==0) {
                LOG(L_ERR, "ERROR: init_tm_stats: no mem for stats\n");
diff --git a/pt.h b/pt.h
index 22f9e6e..11b7005 100644 (file)
--- a/pt.h
+++ b/pt.h
@@ -58,34 +58,8 @@ struct process_table {
 
 extern struct process_table *pt;
 extern int process_no;
-
-/* get number of process started by main with
-   given configuration
-*/
-inline static int process_count()
-{
-       int udp_listeners;
-       struct socket_info* si;
-       
-       for (si=udp_listen, udp_listeners=0; si; si=si->next, udp_listeners++);
-    return 
-               /* receivers and attendant */
-               (dont_fork ? 1 : children_no*udp_listeners + 1)
-               /* timer process */
-               + 1 /* always, we need it in most cases, and we can't tell here
-                          & now if we don't need it */
-#ifdef USE_SLOW_TIMER
-               + 1 /* slow timer process */
-#endif
-               /* fifo server */
-               +((fifo==NULL || strlen(fifo)==0) ? 0 : 1 )
-               /* unixsock server*/
-               +(unixsock_name?unixsock_children:0)
-#ifdef USE_TCP
-               +((!tcp_disable)?( 1/* tcp main */ + tcp_children_no ):0) 
-#endif
-               ;
-}
+extern int process_count;
+extern int last_process;
 
 
 /* return processes pid */
index 44bc988..ba45206 100644 (file)
@@ -1694,7 +1694,7 @@ int tcp_init_children()
                for (si=tls_listen; si; si=si->next, r++);
 #endif
        
-       tcp_max_fd_no=process_count()*2 +r-1 /* timer */ +3; /* stdin/out/err*/
+       tcp_max_fd_no=process_count*2 +r-1 /* timer */ +3; /* stdin/out/err*/
        tcp_max_fd_no+=tcp_max_connections;
        
        /* create the tcp sock_info structures */
@@ -1741,7 +1741,7 @@ int tcp_init_children()
                        /* record pid twice to avoid the child using it, before
                         * parent gets a chance to set it*/
                        pt[process_no].pid=getpid();
-                       if (init_child(r+children_no+1) < 0) {
+                       if (init_child(process_no) < 0) {
                                LOG(L_ERR, "init_children failed\n");
                                goto error;
                        }
index 8519711..bca5004 100644 (file)
@@ -193,7 +193,7 @@ static int ps_cmd(str* msg)
 
        ret = 0;
        unixsock_reply_asciiz("200 OK\n");
-       for (p = 0; p < process_count(); p++) {
+       for (p = 0; p < process_count; p++) {
                if (unixsock_reply_printf("%d\t%d\t%s\n", p, pt[p].pid, pt[p].desc) < 0) {
                        unixsock_reply_reset();
                        unixsock_reply_asciiz("500 Error while printing reply\n");