2
0
Эх сурвалжийг харах

core: global parameters to enable waiting for child one worker initialization

- new paramters:
  - wait_child1_mode=[0|1] - set to wait or not
  - wait_child1_time=1000000 (micro-seconds) - how long to wait over all
  - wait_child1_usleep=100000 (micro-seconds) - step to wait before
  checking if initialization completed
Daniel-Constantin Mierla 4 жил өмнө
parent
commit
699d208adc

+ 6 - 0
src/core/cfg.lex

@@ -467,6 +467,9 @@ VERBOSE_STARTUP		"verbose_startup"
 
 SERVER_ID     "server_id"
 ROUTE_LOCKS_SIZE     "route_locks_size"
+WAIT_CHILD1_MODE     "wait_child1_mode"
+WAIT_CHILD1_TIME     "wait_child1_time"
+WAIT_CHILD1_USLEEP   "wait_child1_usleep"
 
 KEMI     "kemi"
 ONSEND_ROUTE_CALLBACK	"onsend_route_callback"
@@ -989,6 +992,9 @@ IMPORTFILE      "import_file"
 <INITIAL>{VERBOSE_STARTUP}		{	count(); yylval.strval=yytext;
 									return VERBOSE_STARTUP; }
 <INITIAL>{ROUTE_LOCKS_SIZE}  { count(); yylval.strval=yytext; return ROUTE_LOCKS_SIZE; }
+<INITIAL>{WAIT_CHILD1_MODE}  { count(); yylval.strval=yytext; return WAIT_CHILD1_MODE; }
+<INITIAL>{WAIT_CHILD1_TIME}  { count(); yylval.strval=yytext; return WAIT_CHILD1_TIME; }
+<INITIAL>{WAIT_CHILD1_USLEEP}  { count(); yylval.strval=yytext; return WAIT_CHILD1_USLEEP; }
 <INITIAL>{SERVER_ID}  { count(); yylval.strval=yytext; return SERVER_ID;}
 <INITIAL>{KEMI}  { count(); yylval.strval=yytext; return KEMI;}
 <INITIAL>{REPLY_ROUTE_CALLBACK}  { count(); yylval.strval=yytext; return REPLY_ROUTE_CALLBACK;}

+ 7 - 0
src/core/cfg.y

@@ -498,6 +498,9 @@ extern char *default_routename;
 %token VERSION_TABLE_CFG
 %token VERBOSE_STARTUP
 %token ROUTE_LOCKS_SIZE
+%token WAIT_CHILD1_MODE
+%token WAIT_CHILD1_TIME
+%token WAIT_CHILD1_USLEEP
 %token CFG_DESCRIPTION
 %token SERVER_ID
 %token KEMI
@@ -1702,6 +1705,10 @@ assign_stm:
 	| VERBOSE_STARTUP EQUAL error { yyerror("boolean value expected"); }
 	| ROUTE_LOCKS_SIZE EQUAL NUMBER { ksr_route_locks_size=$3; }
 	| ROUTE_LOCKS_SIZE EQUAL error { yyerror("number expected"); }
+	| WAIT_CHILD1_MODE EQUAL NUMBER { ksr_wait_child1_mode=$3; }
+	| WAIT_CHILD1_MODE EQUAL error { yyerror("number expected"); }
+	| WAIT_CHILD1_TIME EQUAL NUMBER { ksr_wait_child1_time=$3; }
+	| WAIT_CHILD1_TIME EQUAL error { yyerror("number expected"); }
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
 	| SERVER_ID EQUAL error  { yyerror("number expected"); }
 	| KEMI DOT ONSEND_ROUTE_CALLBACK EQUAL STRING {

+ 5 - 0
src/core/globals.h

@@ -218,6 +218,11 @@ extern str _ksr_xavp_via_fields;
 extern int ksr_sip_parser_mode;
 extern int ksr_cfg_print_mode;
 
+extern int ksr_wait_child1_mode;
+extern int ksr_wait_child1_time;
+extern int ksr_wait_child1_usleep;
+extern int *ksr_wait_child1_done;
+
 extern char *_sr_uri_host_extra_chars;
 extern unsigned char *_ksr_hname_extra_chars;
 

+ 16 - 1
src/core/tcp_main.c

@@ -5107,7 +5107,19 @@ int tcp_init_children(int *woneinit)
 			LM_ERR("fork failed: %s\n", strerror(errno));
 			goto error;
 		}else if (pid>0){
-			/* parent */
+			/* parent - main process */
+			if(*woneinit==0 && ksr_wait_child1_mode!=0) {
+				int wcount=0;
+				while(*ksr_wait_child1_done==0) {
+					sleep_us(ksr_wait_child1_usleep);
+					wcount++;
+					if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
+						LM_ERR("waiting for child one too long - wait time: %d\n",
+								ksr_wait_child1_time);
+						goto error;
+					}
+				}
+			}
 			*woneinit = 1;
 		}else{
 			/* child */
@@ -5117,6 +5129,9 @@ int tcp_init_children(int *woneinit)
 				if(run_child_one_init_route()<0)
 					goto error;
 			}
+			if(ksr_wait_child1_mode!=0) {
+				*ksr_wait_child1_done = 1;
+			}
 
 			tcp_receive_loop(reader_fd_1);
 		}

+ 45 - 2
src/main.c

@@ -156,7 +156,6 @@
 #endif
 
 
-
 static char help_msg[]= "\
 Usage: " NAME " [options]\n\
 Options:\n\
@@ -541,6 +540,11 @@ static int *_sr_instance_started = NULL;
 int ksr_cfg_print_mode = 0;
 int ksr_atexit_mode = 1;
 
+int ksr_wait_child1_mode = 0;
+int ksr_wait_child1_time = 4000000;
+int ksr_wait_child1_usleep = 100000;
+int *ksr_wait_child1_done = NULL;
+
 /**
  * return 1 if all child processes were forked
  * - note: they might still be in init phase (i.e., child init)
@@ -1651,6 +1655,14 @@ int main_loop(void)
 
 
 		woneinit = 0;
+		if(ksr_wait_child1_mode!=0) {
+			ksr_wait_child1_done=(int*)shm_malloc(sizeof(int));
+			if(ksr_wait_child1_done==0) {
+				SHM_MEM_ERROR;
+				goto error;
+			}
+			*ksr_wait_child1_done = 0;
+		}
 		/* udp processes */
 		for(si=udp_listen; si; si=si->next){
 			nrprocs = (si->workers>0)?si->workers:children_no;
@@ -1689,8 +1701,24 @@ int main_loop(void)
 						if(run_child_one_init_route()<0)
 							goto error;
 					}
+					if(ksr_wait_child1_mode!=0) {
+						*ksr_wait_child1_done = 1;
+					}
 					return udp_rcv_loop();
 				}
+				/* main process */
+				if(woneinit==0 && ksr_wait_child1_mode!=0) {
+					int wcount=0;
+					while(*ksr_wait_child1_done==0) {
+						sleep_us(ksr_wait_child1_usleep);
+						wcount++;
+						if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
+							LM_ERR("waiting for child one too long - wait time: %d\n",
+									ksr_wait_child1_time);
+							goto error;
+						}
+					}
+				}
 				woneinit = 1;
 			}
 			/*parent*/
@@ -1724,9 +1752,24 @@ int main_loop(void)
 							if(run_child_one_init_route()<0)
 								goto error;
 						}
-
+						if(ksr_wait_child1_mode!=0) {
+							*ksr_wait_child1_done = 1;
+						}
 						return sctp_core_rcv_loop();
 					}
+					/* main process */
+					if(woneinit==0 && ksr_wait_child1_mode!=0) {
+						int wcount=0;
+						while(*ksr_wait_child1_done==0) {
+							sleep_us(ksr_wait_child1_usleep);
+							wcount++;
+							if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
+								LM_ERR("waiting for child one too long - wait time: %d\n",
+										ksr_wait_child1_time);
+								goto error;
+							}
+						}
+					}
 					woneinit = 1;
 				}
 			/*parent*/