Browse code

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 authored on 15/03/2021 11:29:08
Showing 5 changed files
... ...
@@ -467,6 +467,9 @@ VERBOSE_STARTUP		"verbose_startup"
467 467
 
468 468
 SERVER_ID     "server_id"
469 469
 ROUTE_LOCKS_SIZE     "route_locks_size"
470
+WAIT_CHILD1_MODE     "wait_child1_mode"
471
+WAIT_CHILD1_TIME     "wait_child1_time"
472
+WAIT_CHILD1_USLEEP   "wait_child1_usleep"
470 473
 
471 474
 KEMI     "kemi"
472 475
 ONSEND_ROUTE_CALLBACK	"onsend_route_callback"
... ...
@@ -989,6 +992,9 @@ IMPORTFILE      "import_file"
989 992
 <INITIAL>{VERBOSE_STARTUP}		{	count(); yylval.strval=yytext;
990 993
 									return VERBOSE_STARTUP; }
991 994
 <INITIAL>{ROUTE_LOCKS_SIZE}  { count(); yylval.strval=yytext; return ROUTE_LOCKS_SIZE; }
995
+<INITIAL>{WAIT_CHILD1_MODE}  { count(); yylval.strval=yytext; return WAIT_CHILD1_MODE; }
996
+<INITIAL>{WAIT_CHILD1_TIME}  { count(); yylval.strval=yytext; return WAIT_CHILD1_TIME; }
997
+<INITIAL>{WAIT_CHILD1_USLEEP}  { count(); yylval.strval=yytext; return WAIT_CHILD1_USLEEP; }
992 998
 <INITIAL>{SERVER_ID}  { count(); yylval.strval=yytext; return SERVER_ID;}
993 999
 <INITIAL>{KEMI}  { count(); yylval.strval=yytext; return KEMI;}
994 1000
 <INITIAL>{REPLY_ROUTE_CALLBACK}  { count(); yylval.strval=yytext; return REPLY_ROUTE_CALLBACK;}
... ...
@@ -498,6 +498,9 @@ extern char *default_routename;
498 498
 %token VERSION_TABLE_CFG
499 499
 %token VERBOSE_STARTUP
500 500
 %token ROUTE_LOCKS_SIZE
501
+%token WAIT_CHILD1_MODE
502
+%token WAIT_CHILD1_TIME
503
+%token WAIT_CHILD1_USLEEP
501 504
 %token CFG_DESCRIPTION
502 505
 %token SERVER_ID
503 506
 %token KEMI
... ...
@@ -1702,6 +1705,10 @@ assign_stm:
1702 1705
 	| VERBOSE_STARTUP EQUAL error { yyerror("boolean value expected"); }
1703 1706
 	| ROUTE_LOCKS_SIZE EQUAL NUMBER { ksr_route_locks_size=$3; }
1704 1707
 	| ROUTE_LOCKS_SIZE EQUAL error { yyerror("number expected"); }
1708
+	| WAIT_CHILD1_MODE EQUAL NUMBER { ksr_wait_child1_mode=$3; }
1709
+	| WAIT_CHILD1_MODE EQUAL error { yyerror("number expected"); }
1710
+	| WAIT_CHILD1_TIME EQUAL NUMBER { ksr_wait_child1_time=$3; }
1711
+	| WAIT_CHILD1_TIME EQUAL error { yyerror("number expected"); }
1705 1712
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
1706 1713
 	| SERVER_ID EQUAL error  { yyerror("number expected"); }
1707 1714
 	| KEMI DOT ONSEND_ROUTE_CALLBACK EQUAL STRING {
... ...
@@ -218,6 +218,11 @@ extern str _ksr_xavp_via_fields;
218 218
 extern int ksr_sip_parser_mode;
219 219
 extern int ksr_cfg_print_mode;
220 220
 
221
+extern int ksr_wait_child1_mode;
222
+extern int ksr_wait_child1_time;
223
+extern int ksr_wait_child1_usleep;
224
+extern int *ksr_wait_child1_done;
225
+
221 226
 extern char *_sr_uri_host_extra_chars;
222 227
 extern unsigned char *_ksr_hname_extra_chars;
223 228
 
... ...
@@ -5107,7 +5107,19 @@ int tcp_init_children(int *woneinit)
5107 5107
 			LM_ERR("fork failed: %s\n", strerror(errno));
5108 5108
 			goto error;
5109 5109
 		}else if (pid>0){
5110
-			/* parent */
5110
+			/* parent - main process */
5111
+			if(*woneinit==0 && ksr_wait_child1_mode!=0) {
5112
+				int wcount=0;
5113
+				while(*ksr_wait_child1_done==0) {
5114
+					sleep_us(ksr_wait_child1_usleep);
5115
+					wcount++;
5116
+					if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
5117
+						LM_ERR("waiting for child one too long - wait time: %d\n",
5118
+								ksr_wait_child1_time);
5119
+						goto error;
5120
+					}
5121
+				}
5122
+			}
5111 5123
 			*woneinit = 1;
5112 5124
 		}else{
5113 5125
 			/* child */
... ...
@@ -5117,6 +5129,9 @@ int tcp_init_children(int *woneinit)
5117 5129
 				if(run_child_one_init_route()<0)
5118 5130
 					goto error;
5119 5131
 			}
5132
+			if(ksr_wait_child1_mode!=0) {
5133
+				*ksr_wait_child1_done = 1;
5134
+			}
5120 5135
 
5121 5136
 			tcp_receive_loop(reader_fd_1);
5122 5137
 		}
... ...
@@ -156,7 +156,6 @@
156 156
 #endif
157 157
 
158 158
 
159
-
160 159
 static char help_msg[]= "\
161 160
 Usage: " NAME " [options]\n\
162 161
 Options:\n\
... ...
@@ -541,6 +540,11 @@ static int *_sr_instance_started = NULL;
541 540
 int ksr_cfg_print_mode = 0;
542 541
 int ksr_atexit_mode = 1;
543 542
 
543
+int ksr_wait_child1_mode = 0;
544
+int ksr_wait_child1_time = 4000000;
545
+int ksr_wait_child1_usleep = 100000;
546
+int *ksr_wait_child1_done = NULL;
547
+
544 548
 /**
545 549
  * return 1 if all child processes were forked
546 550
  * - note: they might still be in init phase (i.e., child init)
... ...
@@ -1651,6 +1655,14 @@ int main_loop(void)
1651 1655
 
1652 1656
 
1653 1657
 		woneinit = 0;
1658
+		if(ksr_wait_child1_mode!=0) {
1659
+			ksr_wait_child1_done=(int*)shm_malloc(sizeof(int));
1660
+			if(ksr_wait_child1_done==0) {
1661
+				SHM_MEM_ERROR;
1662
+				goto error;
1663
+			}
1664
+			*ksr_wait_child1_done = 0;
1665
+		}
1654 1666
 		/* udp processes */
1655 1667
 		for(si=udp_listen; si; si=si->next){
1656 1668
 			nrprocs = (si->workers>0)?si->workers:children_no;
... ...
@@ -1689,8 +1701,24 @@ int main_loop(void)
1689 1701
 						if(run_child_one_init_route()<0)
1690 1702
 							goto error;
1691 1703
 					}
1704
+					if(ksr_wait_child1_mode!=0) {
1705
+						*ksr_wait_child1_done = 1;
1706
+					}
1692 1707
 					return udp_rcv_loop();
1693 1708
 				}
1709
+				/* main process */
1710
+				if(woneinit==0 && ksr_wait_child1_mode!=0) {
1711
+					int wcount=0;
1712
+					while(*ksr_wait_child1_done==0) {
1713
+						sleep_us(ksr_wait_child1_usleep);
1714
+						wcount++;
1715
+						if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
1716
+							LM_ERR("waiting for child one too long - wait time: %d\n",
1717
+									ksr_wait_child1_time);
1718
+							goto error;
1719
+						}
1720
+					}
1721
+				}
1694 1722
 				woneinit = 1;
1695 1723
 			}
1696 1724
 			/*parent*/
... ...
@@ -1724,9 +1752,24 @@ int main_loop(void)
1724 1752
 							if(run_child_one_init_route()<0)
1725 1753
 								goto error;
1726 1754
 						}
1727
-
1755
+						if(ksr_wait_child1_mode!=0) {
1756
+							*ksr_wait_child1_done = 1;
1757
+						}
1728 1758
 						return sctp_core_rcv_loop();
1729 1759
 					}
1760
+					/* main process */
1761
+					if(woneinit==0 && ksr_wait_child1_mode!=0) {
1762
+						int wcount=0;
1763
+						while(*ksr_wait_child1_done==0) {
1764
+							sleep_us(ksr_wait_child1_usleep);
1765
+							wcount++;
1766
+							if(ksr_wait_child1_time<=wcount*ksr_wait_child1_usleep) {
1767
+								LM_ERR("waiting for child one too long - wait time: %d\n",
1768
+										ksr_wait_child1_time);
1769
+								goto error;
1770
+							}
1771
+						}
1772
+					}
1730 1773
 					woneinit = 1;
1731 1774
 				}
1732 1775
 			/*parent*/