- applied patch from Dragos Vingarzan <vingarzan@fokus.fraunhofer.de> which
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 19 Sep 2006 16:13:27 +0000 (16:13 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 19 Sep 2006 16:13:27 +0000 (16:13 +0000)
 moves all the forking part into 2 functions in pt.c (fork_process and
  fork_tcp_process).
- added PROC_NOCHLDINIT rank value for Dragos's fork_process (if this
 value is used as child_id/rank_value the mod_child functions will not be
  called)
- added register_procs(processes_no), used from mod_init when a module
 knows that it will fork some children (replaces the old process_count++
  / the patch's estimated_process_count++)
- added get_max_procs(): returns the maximum (estimated) number of
  processes

Makefile.defs
core_cmd.c
doc/dns.txt
doc/dst_blacklist.txt
main.c
modules/tm/t_stats.c
modules/tm/tm.c
pt.h
sr_module.h
tcp_init.h
tcp_main.c

index a97fbe8..e5d9761 100644 (file)
@@ -66,7 +66,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev44-dns_cache
+EXTRAVERSION = -dev45-dns_cache
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
                        $(SUBLEVEL) )
index 6118683..46dbc09 100644 (file)
@@ -216,7 +216,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->add(c, "d", pt[p].pid);
                rpc->add(c, "s", pt[p].desc);
        }
index 70827e9..bbc618e 100644 (file)
@@ -13,7 +13,7 @@ Overview
   and negative) and look first in its internal cache.
  When its internal dns cache is enabled, ser can also use dns failover: if
   one destination resolves to multiple addresses ser can try all of them until
-  it finds one to which it can succesfully send the packet or it exhausts all 
+  it finds one to which it can successfully send the packet or it exhausts all 
   of them. ser (tm to be more precise) uses the dns failover also when the
   destination host doesn't send any reply to a forwarded invite within the
   sip timeout interval (whose value can be configured using the tm fr_timer
@@ -27,19 +27,19 @@ DNS Cache and Failover Drawbacks
   1. only the locally configured dns server (usually in /etc/resolv.conf) is
   used for the requests (/etc/hosts and the local Network Information Service
   are ignored). 
-     Workarround: disable the dns cache (use_dns_cache=off or
+     Workaround: disable the dns cache (use_dns_cache=off or
   compile without -DUSE_DNS_CACHE).
 
   2. the dns cache uses extra memory
-      Workarround: disable the dns cache.
+      Workaround: disable the dns cache.
 
   3. the dns failover introduces a very small performance penalty 
-     Workarround: disable the dns failover (use_dns_failover=off).
+     Workaround: disable the dns failover (use_dns_failover=off).
 
   4. the dns failover increases the memory usage (the internal structures
   used to represent the transaction are bigger when the dns failover support is
   compiled).
-     Workarround: compile without dns failover support (-DUSE_DNS_FAILOVER).
+     Workaround: compile without dns failover support (-DUSE_DNS_FAILOVER).
   Turning it off from the config file is not enough in this case (the extra
    memory will still be used).
 
@@ -94,7 +94,7 @@ DNS Resolver Options
  server configured in /etc/resolv.conf, set the dns resolver options in ser's
  config as in the above example and enable the dns cache (in ser).
  Pay particular attention to dns_servers_no and dns_use_search_list. It's a
- good ideea to make sure you don't need / use the search list or more then one
+ good idea to make sure you don't need / use the search list or more then one
  dns server (to avoid unnecessary extra lookups).
 
 
index 516e116..be6872d 100644 (file)
@@ -22,7 +22,7 @@ Drawbacks
  Using the destination blacklist will cause some performance degradation,
  especially on multi cpu machines. If you don't need it you can easily
   disable it, either in ser's config or at compile time. Disabling it at
-  compile time is sligthly better (but not in a "measurable" way) then
+  compile time is slightly better (but not in a "measurable" way) then
    disabling it at runtime, from the config file.
  Whether the destination blacklist is better to be on or off depends a lot
   on the setup. In general is better to turn it on when:
@@ -47,7 +47,7 @@ Config Variables
   Note: using the blacklist incurs a small performance penalty.
 
  dst_blacklist_mem = size in Kb (default 250 Kb) - maximum
-  shared memory ammount used for keeping the blacklisted destinations.
+  shared memory amount used for keeping the blacklisted destinations.
 
  dst_blacklist_expire = time in s (default 60 s) - how much time a 
   blacklisted destination will be kept in the blacklist (w/o any update).
@@ -66,4 +66,4 @@ Compile Options
    form DEFS list. To add a compile options add it to the make command line,
      e.g.: make proper; make all extra_defs=-DUSE_DNS_FAILOVER
    or for a permanent solution, edit Makefile.defs and add it to DEFS 
-   (don't foget to prefix it with -D).
+   (don't forget to prefix it with -D).
diff --git a/main.c b/main.c
index e6beab0..ca36000 100644 (file)
--- a/main.c
+++ b/main.c
@@ -246,8 +246,14 @@ int tcp_disable = 0; /* 1 if tcp is disabled */
 #ifdef USE_TLS
 int tls_disable = 0; /* 1 if tls is disabled */
 #endif
+
 struct process_table *pt=0;            /*array with children pids, 0= main proc,
                                                                        alloc'ed in shared mem if possible*/
+int *process_count = 0;                        /* Total number of SER processes currently 
+                                                                  running */
+gen_lock_t* process_lock;              /* lock on the process table */
+int process_no = 0;                            /* index of process in the pt */
+
 int sig_flag = 0;              /* last signal received */
 int debug = L_DEFAULT; /* print only msg. < L_WARN */
 int dont_fork = 0;
@@ -349,20 +355,9 @@ unsigned short tls_port_no=0; /* default port */
 
 struct host_alias* aliases=0; /* name aliases list */
 
-/* ipc related globals */
-int process_no = 0;
-
 /* Parameter to child_init */
 int child_rank = 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
@@ -456,9 +451,17 @@ static void kill_all_children(int signum)
        int r;
 
        if (own_pgid) kill(0, signum);
-       else if (pt)
-               for (r=1; r<process_count; r++)
-                       if (pt[r].pid) kill(pt[r].pid, signum);
+       else if (pt){
+               lock_get(process_lock);
+               for (r=1; r<*process_count; r++){
+                       if (pt[r].pid) {
+                               kill(pt[r].pid, signum);
+                       }
+                       else LOG(L_CRIT, "BUG: killing: %s > %d no pid!!!\n",
+                                                       pt[r].desc, pt[r].pid);
+               }
+               lock_release(process_lock);
+       }
 }
 
 
@@ -803,9 +806,6 @@ int main_loop()
        int  i;
        pid_t pid;
        struct socket_info* si;
-#ifdef USE_TCP
-       int sockfd[2];
-#endif
 #ifdef EXTRA_DEBUG
        int r;
 #endif
@@ -838,53 +838,34 @@ int main_loop()
 
 #ifdef USE_SLOW_TIMER
                /* we need another process to act as the "slow" timer*/
-                               process_no++;
-                               if ((pid=fork())<0){
+                               pid = fork_process(PROC_TIMER, "slow timer", 0);
+                               if (pid<0){
                                        LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
                                        goto error;
                                }
                                if (pid==0){
                                        /* child */
-                                       pt[process_no].pid=getpid();
                                        /* timer!*/
                                        /* process_bit = 0; */
-                                       if (init_child(PROC_TIMER) < 0) {
-                                               LOG(L_ERR, "slow timer: init_child failed\n");
-                                               goto error;
-                                       }
-
                                        if (arm_slow_timer()<0) goto error;
                                        slow_timer_main();
                                }else{
-                                       pt[process_no].pid=pid; /*should be shared mem anyway*/
-                                       strncpy(pt[process_no].desc, "slow timer", MAX_PT_DESC );
                                        slow_timer_pid=pid;
-
                                }
 #endif
                                /* we need another process to act as the "main" timer*/
-                               process_no++;
-                               if ((pid=fork())<0){
+                               pid = fork_process(PROC_TIMER, "timer", 0);
+                               if (pid<0){
                                        LOG(L_CRIT,  "ERROR: main_loop: Cannot fork\n");
                                        goto error;
                                }
                                if (pid==0){
                                        /* child */
-                                       /* record pid twice to avoid the child using it, before
-                                        * parent gets a chance to set it*/
-                                       pt[process_no].pid=getpid();
                                        /* timer!*/
                                        /* process_bit = 0; */
-                                       if (init_child(PROC_TIMER) < 0) {
-                                               LOG(L_ERR, "timer: init_child failed\n");
-                                               goto error;
-                                       }
-
                                        if (arm_timer()<0) goto error;
                                        timer_main();
                                }else{
-                                               pt[process_no].pid=pid; /*should be shared mem anyway*/
-                                               strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
                                }
 
                /* main process, receive loop */
@@ -910,9 +891,6 @@ int main_loop()
 
                return udp_rcv_loop();
        }else{
-               /* process_no now initialized to zero -- increase from now on
-                  as new processes are forked (while skipping 0 reserved for main )
-               */
 
                for(si=udp_listen;si;si=si->next){
                        /* create the listening socket (for each address)*/
@@ -967,53 +945,22 @@ int main_loop()
                /* udp processes */
                for(si=udp_listen; si; si=si->next){
                        for(i=0;i<children_no;i++){
-                               process_no++;
                                child_rank++;
-#ifdef USE_TCP
-                               if(!tcp_disable){
-                                       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
-                                               LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
-                                                       strerror(errno));
-                                               goto error;
-                                       }
-                               }
-#endif
-                               if ((pid=fork())<0){
+                               pid = fork_process(child_rank, "udp", 1);
+                               if (pid<0){
                                        LOG(L_CRIT,  "main_loop: Cannot fork\n");
                                        goto error;
                                }else if (pid==0){
-                                            /* child */
-#ifdef USE_TCP
-                                       if (!tcp_disable){
-                                               close(sockfd[0]);
-                                               unix_tcp_sock=sockfd[1];
-                                       }
-#endif
-                                       /* record pid twice to avoid the child using it, before
-                                        * parent gets a chance to set it*/
-                                       pt[process_no].pid=getpid();
+                                       /* child */
                                        bind_address=si; /* shortcut */
-                                       if (init_child(child_rank) < 0) {
-                                               LOG(L_ERR, "init_child failed\n");
-                                               goto error;
-                                       }
 #ifdef STATS
                                        setstats( i+r*children_no );
 #endif
                                        return udp_rcv_loop();
                                }else{
-                                               pt[process_no].pid=pid; /*should be in shared mem.*/
                                                snprintf(pt[process_no].desc, MAX_PT_DESC,
                                                        "receiver child=%d sock= %s:%s", i,
                                                        si->name.s, si->port_no_str.s );
-#ifdef USE_TCP
-                                               if (!tcp_disable){
-                                                       close(sockfd[1]);
-                                                       pt[process_no].unix_sock=sockfd[0];
-                                                       pt[process_no].idx=-1; /* this is not a "tcp"
-                                                                                                         process*/
-                                               }
-#endif
                                }
                        }
                        /*parent*/
@@ -1027,94 +974,32 @@ int main_loop()
 
        {
 #ifdef USE_SLOW_TIMER
-#ifdef USE_TCP
-               if (!tcp_disable){
-                       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
-                               LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
-                                       strerror(errno));
-                               goto error;
-                       }
-               }
-#endif
                /* fork again for the "slow" timer process*/
-               process_no++;
-               if ((pid=fork())<0){
+               pid = fork_process(PROC_TIMER, "slow timer", 1);
+               if (pid<0){
                        LOG(L_CRIT, "main_loop: cannot fork \"slow\" timer process\n");
                        goto error;
                }else if (pid==0){
                        /* child */
                        /* is_main=0; */
-#ifdef USE_TCP
-                       if (!tcp_disable){
-                               close(sockfd[0]);
-                               unix_tcp_sock=sockfd[1];
-                       }
-#endif
-                       /* 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(PROC_TIMER) < 0) {
-                               LOG(L_ERR, "slow timer: init_child failed\n");
-                               goto error;
-                       }
                        if (arm_slow_timer()<0) goto error;
                        slow_timer_main();
                }else{
-                       pt[process_no].pid=pid;
-                       strncpy(pt[process_no].desc, "slow timer", MAX_PT_DESC );
                        slow_timer_pid=pid;
-#ifdef USE_TCP
-                       if(!tcp_disable){
-                                               close(sockfd[1]);
-                                               pt[process_no].unix_sock=sockfd[0];
-                                               pt[process_no].idx=-1; /* this is not a "tcp" process*/
-                       }
-#endif
                }
 #endif /* USE_SLOW_TIMER */
 
                /* fork again for the "main" timer process*/
-#ifdef USE_TCP
-               if (!tcp_disable){
-                       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
-                               LOG(L_ERR, "ERROR: main_loop: socketpair failed: %s\n",
-                                       strerror(errno));
-                               goto error;
-                       }
-               }
-#endif
-               process_no++;
-               if ((pid=fork())<0){
+               pid = fork_process(PROC_TIMER, "timer", 1);
+               if (pid<0){
                        LOG(L_CRIT, "main_loop: cannot fork timer process\n");
                        goto error;
                }else if (pid==0){
                        /* child */
                        /* is_main=0; */
-#ifdef USE_TCP
-                       if (!tcp_disable){
-                               close(sockfd[0]);
-                               unix_tcp_sock=sockfd[1];
-                       }
-#endif
-                       /* 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(PROC_TIMER) < 0) {
-                               LOG(L_ERR, "timer: init_child failed\n");
-                               goto error;
-                       }
                        if (arm_timer()<0) goto error;
                        timer_main();
                }else{
-                       pt[process_no].pid=pid;
-                       strncpy(pt[process_no].desc, "timer", MAX_PT_DESC );
-#ifdef USE_TCP
-                       if(!tcp_disable){
-                                               close(sockfd[1]);
-                                               pt[process_no].unix_sock=sockfd[0];
-                                               pt[process_no].idx=-1; /* this is not a "tcp" process*/
-                       }
-#endif
                }
        }
 #ifdef USE_TCP
@@ -1122,33 +1007,20 @@ int main_loop()
                                /* start tcp  & tls receivers */
                        if (tcp_init_children()<0) goto error;
                                /* start tcp+tls master proc */
-                       process_no++;
-                       if ((pid=fork())<0){
+                       pid = fork_process(PROC_TCP_MAIN, "tcp main process", 0);
+                       if (pid<0){
                                LOG(L_CRIT, "main_loop: cannot fork tcp main process: %s\n",
                                                        strerror(errno));
                                goto error;
                        }else if (pid==0){
                                /* child */
-                               /* is_main=0; */
-                               /* 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(PROC_TCP_MAIN) < 0) {
-                                       LOG(L_ERR, "tcp_main: error in init_child\n");
-                                       goto error;
-                               }
                                tcp_main_loop();
                        }else{
-                               pt[process_no].pid=pid;
-                               strncpy(pt[process_no].desc, "tcp main process", MAX_PT_DESC );
-                               pt[process_no].unix_sock=-1;
-                               pt[process_no].idx=-1; /* this is not a "tcp" process*/
                                unix_tcp_sock=-1;
                        }
                }
 #endif
        /* main */
-       pt[0].pid=getpid();
        strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
 #ifdef USE_TCP
        if(!tcp_disable){
@@ -1159,11 +1031,6 @@ int main_loop()
 #endif
        /*DEBUG- remove it*/
 
-       /* 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;
 
@@ -1174,7 +1041,7 @@ int main_loop()
 
        /*DEBUG- remove it*/
 #ifdef EXTRA_DEBUG
-       for (r=0; r<process_count; r++){
+       for (r=0; r<*process_count; r++){
                fprintf(stderr, "% 3d   % 5d - %s\n", r, pt[r].pid, pt[r].desc);
        }
 #endif
@@ -1326,15 +1193,15 @@ int main(int argc, char** argv)
                                        break;
                        case '?':
                                        if (isprint(optopt))
-                                               fprintf(stderr, "Unknown option `-%c´. Use -h for help.\n", optopt);
+                                               fprintf(stderr, "Unknown option `-%c. Use -h for help.\n", optopt);
                                        else
                                                fprintf(stderr,
-                                                               "Unknown option character `\\x%x´. Use -h for help.\n",
+                                                               "Unknown option character `\\x%x. Use -h for help.\n",
                                                                optopt);
                                        goto error;
                        case ':':
                                        fprintf(stderr,
-                                                               "Option `-%c´ requires an argument. Use -h for help.\n",
+                                                               "Option `-%c requires an argument. Use -h for help.\n",
                                                                optopt);
                                        goto error;
                        default:
@@ -1645,32 +1512,22 @@ 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");
+       /* initialize process_table, add core process no. (calc_proc_no()) to the 
+        * processes registered from the modules*/
+       if (init_pt(calc_proc_no())==-1)
                goto error;
-       }
-       memset(pt, 0, sizeof(struct process_table)*process_count);
+       
+       /* The total number of processes is now known, note that no
+        * function being called before this point may rely on the
+        * number of processes !
+        */
+       DBG("Expect (at least) %d SER processes in your process list\n",
+                       get_max_procs());
 
        /* fix routing lists */
        if ( (r=fix_rls())!=0){
index 0d7d393..46cca3a 100644 (file)
@@ -58,7 +58,7 @@ int init_tm_stats(void)
             /* Delay initialization of tm_stats structures to
              * init_tm_stats_child which gets called from child_init,
              * in mod_init function other modules can increase the value of
-             * process_count and thus we do not know about processes created
+             * estimated_process_count and thus we do not know about processes created
              * from modules which get loaded after tm and thus their mod_init
              * functions will be called after tm mod_init function finishes
              */
@@ -70,10 +70,10 @@ int init_tm_stats_child(void)
 {
        int size;
 
-            /* We are called from child_init, process_count has definitive
+            /* We are called from child_init, estimated_process_count has definitive
              * value now and thus we can safely allocate the variables
              */
-       size = sizeof(stat_counter) * process_count;
+       size = sizeof(stat_counter) * get_max_procs();
        tm_stats->s_waiting = shm_malloc(size);
        if (tm_stats->s_waiting == 0) {
                ERR("No mem for stats\n");
@@ -135,7 +135,7 @@ void tm_rpc_stats(rpc_t* rpc, void* c)
        unsigned long total, current, waiting, total_local;
        int i, pno;
 
-       pno = process_count;
+       pno = get_max_procs();
        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];
index aac05e1..de94b8d 100644 (file)
@@ -511,7 +511,7 @@ static int mod_init(void)
 
             /* First tm_stat initialization function only allocates the top level stat
              * structure in shared memory, the initialization will complete in child
-             * init with init_tm_stats_child when the final value of process_count is
+             * init with init_tm_stats_child when the final value of estimated_process_count is
              * known
              */
        if (init_tm_stats() < 0) {
diff --git a/pt.h b/pt.h
index 11b7005..d8fed44 100644 (file)
--- a/pt.h
+++ b/pt.h
@@ -32,6 +32,7 @@
  * History:
  * --------
  *  2003-04-15  added tcp_disable support (andrei)
+ *  2006-06-14 added process table in shared mem (dragos)
  */
 
 
 
 #include <sys/types.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include "globals.h"
 #include "timer.h"
 #include "socket_info.h"
+#include "locking.h"
 
-#define MAX_PT_DESC    128
+#define MAX_PT_DESC                    128
 
 struct process_table {
        int pid;
 #ifdef USE_TCP
-       int unix_sock; /* unix socket on which tcp main listens */
-       int idx; /* tcp child index, -1 for other processes */
+       int unix_sock;  /* unix socket on which tcp main listens        */
+       int idx;                /* tcp child index, -1 for other processes      */
 #endif
        char desc[MAX_PT_DESC];
 };
 
 extern struct process_table *pt;
+extern gen_lock_t* process_lock;
+extern int *process_count;
 extern int process_no;
-extern int process_count;
-extern int last_process;
 
+extern struct tcp_child* tcp_children;
+
+inline int init_pt();
+int get_max_procs();
+int register_procs(int no);
 
 /* return processes pid */
-inline static int my_pid()
-{
-       return pt ? pt[process_no].pid : getpid();
-}
+inline int my_pid();
+
+/**
+ * Forks a new process.
+ * @param desc - text description for the process table
+ * @param make_sock - if to create a unix socket pair for it
+ * @returns the pid of the new process
+ */
+inline int fork_process(int child_id,char *desc,int make_sock);
 
+/**
+ * Forks a new TCP process.
+ * @param desc - text description for the process table
+ * @param r - index in the tcp_children array
+ * @param *reader_fd_1 - pointer to return the reader_fd[1]
+ * @returns the pid of the new process
+ */
+inline int fork_tcp_process(int child_id,char *desc,int r,int *reader_fd_1);
 
 #endif
index 327f67f..77f077c 100644 (file)
@@ -87,6 +87,8 @@ typedef int (*param_func_t)( modparam_t type, void* val);
 #define PROC_FIFO     -2  /* FIFO attendant process */
 #define PROC_TCP_MAIN -4  /* TCP main process */
 #define PROC_UNIXSOCK -5  /* Unix socket server */
+#define PROC_NOCHLDINIT -128 /* no child init functions will be called
+                                if this rank is used in fork_process() */
 
 #define PROC_MIN PROC_UNIXSOCK /* Minimum process rank */
 
index 2d5d567..861cf91 100644 (file)
 #define tcp_init_h
 #include "ip_addr.h"
 
+struct tcp_child{
+       pid_t pid;
+       int proc_no; /* ser proc_no, for debugging */
+       int unix_sock; /* unix "read child" sock fd */
+       int busy;
+       int n_reqs; /* number of requests serviced so far */
+};
+
+
 int init_tcp();
 void destroy_tcp();
 int tcp_init(struct socket_info* sock_info);
 int tcp_init_children();
 void tcp_main_loop();
 void tcp_receive_loop(int unix_sock);
+int tcp_fix_child_sockets(int* fd);
 
 
 #endif
index 93f2121..41e704d 100644 (file)
 enum fd_types { F_NONE, F_SOCKINFO /* a tcp_listen fd */,
                                F_TCPCONN, F_TCPCHILD, F_PROC };
 
-struct tcp_child{
-       pid_t pid;
-       int proc_no; /* ser proc_no, for debugging */
-       int unix_sock; /* unix "read child" sock fd */
-       int busy;
-       int n_reqs; /* number of requests serviced so far */
-};
-
 
 
 int tcp_accept_aliases=0; /* by default don't accept aliases */
@@ -175,7 +167,7 @@ struct tcp_conn_alias** tcpconn_aliases_hash=0;
 struct tcp_connection** tcpconn_id_hash=0;
 gen_lock_t* tcpconn_lock=0;
 
-static struct tcp_child* tcp_children;
+struct tcp_child* tcp_children;
 static int* connection_id=0; /*  unique for each connection, used for 
                                                                quickly finding the corresponding connection
                                                                for a reply */
@@ -1919,7 +1911,7 @@ error:
 }
 
 
-
+#ifdef TCP_CHILD_NON_BLOCKING
 /* returns -1 on error */
 static int set_non_blocking(int s)
 {
@@ -1941,14 +1933,28 @@ error:
        return -1;
 }
 
+#endif
+
+
+/*  returns -1 on error, 0 on success */
+int tcp_fix_child_sockets(int* fd)
+{
+#ifdef TCP_CHILD_NON_BLOCKING
+       if ((set_non_blocking(fd[0])<0) ||
+               (set_non_blocking(fd[1])<0)){
+               return -1;
+       }
+#endif
+       return 0;
+}
+
 
 
 /* starts the tcp processes */
 int tcp_init_children()
 {
        int r;
-       int sockfd[2];
-       int reader_fd[2]; /* for comm. with the tcp children read  */
+       int reader_fd_1; /* for comm. with the tcp children read  */
        pid_t pid;
        struct socket_info *si;
        
@@ -1962,11 +1968,11 @@ 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*/
-       /* max connections can be temporarily exceeded with process_count
+       tcp_max_fd_no=get_max_procs()*2 +r-1 /* timer */ +3; /* stdin/out/err*/
+       /* max connections can be temporarily exceeded with estimated_process_count
         * - tcp_main (tcpconn_connect called simultaneously in all all the 
         *  processes) */
-       tcp_max_fd_no+=tcp_max_connections+process_count-1 /* tcp main */;
+       tcp_max_fd_no+=tcp_max_connections+get_max_procs()-1 /* tcp main */;
        
        /* alloc the children array */
        tcp_children=pkg_malloc(sizeof(struct tcp_child)*tcp_children_no);
@@ -1979,60 +1985,19 @@ int tcp_init_children()
        
        /* fork children & create the socket pairs*/
        for(r=0; r<tcp_children_no; r++){
-               if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
-                       LOG(L_ERR, "ERROR: tcp_main: socketpair failed: %s\n",
-                                       strerror(errno));
-                       goto error;
-               }
-               if (socketpair(AF_UNIX, SOCK_STREAM, 0, reader_fd)<0){
-                       LOG(L_ERR, "ERROR: tcp_main: socketpair failed: %s\n",
-                                       strerror(errno));
-                       goto error;
-               }
-#ifdef TCP_CHILD_NON_BLOCKING
-               if ((set_non_blocking(reader_fd[0])<0) || 
-                       (set_non_blocking(reader_fd[1])<0)){
-                       LOG(L_ERR, "ERROR: tcp_main: failed to set non blocking"
-                                               "on child sockets\n");
-                       /* continue, it's not critical (it will go slower under
-                        * very high connection rates) */
-               }
-#endif
-               
-               process_no++;
                child_rank++;
-               pid=fork();
+               pid=fork_tcp_process(child_rank,"tcp receiver",1,&reader_fd_1);
                if (pid<0){
                        LOG(L_ERR, "ERROR: tcp_main: fork failed: %s\n",
                                        strerror(errno));
                        goto error;
                }else if (pid>0){
                        /* parent */
-                       close(sockfd[1]);
-                       close(reader_fd[1]);
-                       tcp_children[r].pid=pid;
-                       tcp_children[r].proc_no=process_no;
-                       tcp_children[r].busy=0;
-                       tcp_children[r].n_reqs=0;
-                       tcp_children[r].unix_sock=reader_fd[0];
-                       pt[process_no].pid=pid;
-                       pt[process_no].unix_sock=sockfd[0];
-                       pt[process_no].idx=r;
-                       strncpy(pt[process_no].desc, "tcp receiver", MAX_PT_DESC);
                }else{
                        /* child */
-                       close(sockfd[0]);
-                       unix_tcp_sock=sockfd[1];
                        bind_address=0; /* force a SEGFAULT if someone uses a non-init.
                                                           bind address on tcp */
-                       /* 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(child_rank) < 0) {
-                               LOG(L_ERR, "init_children failed\n");
-                               goto error;
-                       }
-                       tcp_receive_loop(reader_fd[1]);
+                       tcp_receive_loop(reader_fd_1);
                }
        }
        return 0;