Browse Source

Adds checks & log messages on semaphore errors

Yann Weber 4 years ago
parent
commit
0b8ade32d9
4 changed files with 43 additions and 8 deletions
  1. 1
    1
      src/conf.c
  2. 1
    4
      src/pyworker.c
  3. 32
    2
      src/responder.c
  4. 9
    1
      src/stats.c

+ 1
- 1
src/conf.c View File

@@ -260,7 +260,7 @@ int pyfcgi_wd_init(void (*wd_sig_cleaner)(int), const struct timespec *delay)
260 260
 	PyFCGI_conf.context.wd_killdelay = timeout;
261 261
 
262 262
 	pyfcgi_log(LOG_DEBUG,
263
-		"Set watchdog with %d.%09ds timeout (%d.%09ds for SIGKILL)",
263
+		"Set KILL watchdog with %d.%09ds timeout (%d.%09ds)",
264 264
 		PyFCGI_conf.context.wd_delay.tv_sec,
265 265
 		PyFCGI_conf.context.wd_delay.tv_nsec,
266 266
 		PyFCGI_conf.context.wd_killdelay.tv_sec,

+ 1
- 4
src/pyworker.c View File

@@ -618,17 +618,14 @@ static void worker_set_busy()
618 618
 	 * maybe to nanosleep 0.01s and retry a sem_trywait... SysV sem are
619 619
 	 * better T_T
620 620
 	 */
621
-#ifdef DEBUG
622 621
 	if(sem_trywait(PyFCGI_SEM(SEM_WSTATE).sem) < 0)
623
-#else
624
-	if(sem_wait(PyFCGI_SEM(SEM_WSTATE).sem) < 0)
625
-#endif
626 622
 	{
627 623
 		err = errno;
628 624
 		if(err == EAGAIN)
629 625
 		{ //panic
630 626
 			pyfcgi_log(LOG_ALERT, "Unable to set busy ! WSTATE sem is allready 0 !!!");
631 627
 			_worker_idle = 0;
628
+			kill(PyFCGI_conf.context.ppid, SIGTERM);
632 629
 			return;
633 630
 		}
634 631
 		pyfcgi_log(LOG_ERR, "error decrementing the WSTATE semaphore : %s",

+ 32
- 2
src/responder.c View File

@@ -22,6 +22,10 @@
22 22
  * @ingroup work_master_proc */
23 23
 static void clean_exit(int status)
24 24
 {
25
+	if(PyFCGI_conf.context.n_wrk)
26
+	{
27
+		kill(PyFCGI_conf.context.pid, SIGTERM);
28
+	}
25 29
 	pyfcgi_IPC_close(IPC_WSTATE | IPC_WREQS | IPC_SEMST | IPC_SHMST);
26 30
 	pyfcgi_IPC_destroy(IPC_WSTATE | IPC_WREQS | IPC_SEMST | IPC_SHMST);
27 31
 	exit(status);
@@ -166,6 +170,8 @@ int responder_loop()
166 170
 		PyFCGI_conf.context.n_wrk = n_wrk;
167 171
 		if(last_update != (now = time(NULL)))
168 172
 		{
173
+pyfcgi_log(LOG_DEBUG, "Infos : n_wrk=%d max=%d min=%d",
174
+	n_wrk, PyFCGI_conf.max_wrk, PyFCGI_conf.min_wrk);
169 175
 			pyfcgi_pool_shm_update(n_wrk);
170 176
 			last_update = now;
171 177
 		}
@@ -191,11 +197,19 @@ int responder_loop()
191 197
 			}
192 198
 			if(WIFSIGNALED(status))
193 199
 			{
200
+				if(WTERMSIG(status) == 9)
201
+				{
202
+					pyfcgi_log(LOG_ALERT,
203
+						"Worker[%d] get killed ! No guaranty that SEM_WSTATE is OK, exiting...",
204
+						n);
205
+					clean_exit(PYFCGI_WORKER_FAIL);
206
+				}
194 207
 				if(WTERMSIG(status) == 11)
195 208
 				{
196 209
 					pyfcgi_log(LOG_ALERT,
197
-						"Worker[%d] segfault !",
210
+						"Worker[%d] segfault ! No guaranty that SEM_WSTATE is OK, exiting...",
198 211
 						n);
212
+					clean_exit(PYFCGI_WORKER_FAIL);
199 213
 				}
200 214
 				else
201 215
 				{
@@ -442,7 +456,13 @@ int pyfcgi_pool_idle(const struct timespec *timeout)
442 456
 				clean_exit(PYFCGI_FATAL);
443 457
 		}
444 458
 	}
445
-	sem_post(PyFCGI_SEM(SEM_WSTATE).sem); //Hope no worker fails to set busy...
459
+	if(sem_post(PyFCGI_SEM(SEM_WSTATE).sem) < 0)
460
+	{
461
+		pyfcgi_log(LOG_ALERT,
462
+			"Unable to sempost after a sem_timedwait : %s",
463
+			strerror(errno));
464
+		clean_exit(PYFCGI_FATAL);
465
+	}
446 466
 	return 1; //idle
447 467
 }
448 468
 
@@ -493,6 +513,7 @@ void pool_sighandler(int signum)
493 513
 		}
494 514
 		
495 515
 	}
516
+	PyFCGI_conf.context.n_wrk = 0;
496 517
 	clean_exit(0);
497 518
 }
498 519
 
@@ -553,9 +574,14 @@ void pyfcgi_pool_shm_update(int nworker)
553 574
 
554 575
 	data = (pyfcgi_stats_shm_t*)PyFCGI_conf.shm.ptr;
555 576
 	data->nworker = nworker;
577
+	err = 0;
556 578
 	if(sem_getvalue(PyFCGI_SEM(SEM_WSTATE).sem, &(data->pool_load)) < 0)
557 579
 	{
558 580
 		data->pool_load = -1;
581
+		pyfcgi_log(LOG_ALERT,
582
+			"Unable to get semaphore value for SEM_WSTATE : ",
583
+			strerror(errno));
584
+		err = 1;
559 585
 	}
560 586
 
561 587
 	if(sem_post(PyFCGI_SEM(SEM_STATS).sem) < 0)
@@ -564,5 +590,9 @@ void pyfcgi_pool_shm_update(int nworker)
564 590
 			strerror(errno));
565 591
 		clean_exit(PYFCGI_FATAL);
566 592
 	}
593
+	if(err)
594
+	{
595
+		clean_exit(PYFCGI_FATAL);
596
+	}
567 597
 }
568 598
 

+ 9
- 1
src/stats.c View File

@@ -359,13 +359,21 @@ int pyfcgi_stats_get_shm(pyfcgi_stats_shm_t *res)
359 359
 
360 360
 	*res = *(pyfcgi_stats_shm_t*)PyFCGI_conf.shm.ptr;
361 361
 
362
+	err = 0;
363
+	if(res->pool_load == -1)
364
+	{
365
+		pyfcgi_log(LOG_INFO,
366
+			"Dropping data : pool_handler seems to encounter problems");
367
+		err = 1;
368
+		memset(res, 0, sizeof(pyfcgi_stats_shm_t));
369
+	}
362 370
 	if(sem_post(PyFCGI_SEM(SEM_STATS).sem) < 0)
363 371
 	{
364 372
 		pyfcgi_log(LOG_ALERT, "Unable to post sem at shm update : %s",
365 373
 			strerror(errno));
366 374
 		return -1;
367 375
 	}
368
-	return 0;
376
+	return err?-1:0;
369 377
 }
370 378
 
371 379
 

Loading…
Cancel
Save