Browse Source

Should fix #35

The problem seems to appear when a worker fails to wait indicate it is idle
by waiting the WSTATE semaphore (maybe when pool handler waited the sem
to check pool's busyness and before the pool handler post it again...)
Yann Weber 4 years ago
parent
commit
9a01ba69b9
2 changed files with 45 additions and 10 deletions
  1. 34
    10
      src/pyworker.c
  2. 11
    0
      src/stats.c

+ 34
- 10
src/pyworker.c View File

@@ -610,6 +610,11 @@ static void worker_set_idle()
610 610
 static void worker_set_busy()
611 611
 {
612 612
 	int err;
613
+	short retry;
614
+	struct timespec timeout;
615
+	timeout.tv_sec = 0;
616
+	timeout.tv_nsec = 100000; //0.0001s
617
+
613 618
 	if(!_worker_idle) { return; }
614 619
 	/**@todo The pool handler WILL decrement the sem to figure if the pool
615 620
 	 * is busy -__- Using sem_wait make sure that the worker will be able
@@ -618,18 +623,37 @@ static void worker_set_busy()
618 623
 	 * maybe to nanosleep 0.01s and retry a sem_trywait... SysV sem are
619 624
 	 * better T_T
620 625
 	 */
621
-	if(sem_trywait(PyFCGI_SEM(SEM_WSTATE).sem) < 0)
626
+	err = 0;
627
+	retry = 10;
628
+	do
622 629
 	{
623
-		err = errno;
624
-		if(err == EAGAIN)
625
-		{ //panic
626
-			pyfcgi_log(LOG_ALERT, "Unable to set busy ! WSTATE sem is allready 0 !!!");
627
-			_worker_idle = 0;
628
-			kill(PyFCGI_conf.context.ppid, SIGTERM);
629
-			return;
630
+		err = 0;
631
+		if(sem_trywait(PyFCGI_SEM(SEM_WSTATE).sem) < 0)
632
+		{
633
+			err = errno;
634
+			if(err == EAGAIN)
635
+			{
636
+				nanosleep(&timeout, NULL);
637
+				err = 1;
638
+			}
639
+			else
640
+			{
641
+				pyfcgi_log(LOG_ERR,
642
+					"error decrementing the WSTATE semaphore : %s",
643
+					strerror(err));
644
+				kill(PyFCGI_conf.context.ppid, SIGTERM);
645
+				return;
646
+			}
630 647
 		}
631
-		pyfcgi_log(LOG_ERR, "error decrementing the WSTATE semaphore : %s",
632
-			strerror(err));
648
+		retry--;
649
+	}while(err & retry);
650
+	if(err)
651
+	{
652
+		pyfcgi_log(LOG_ALERT,
653
+			"Unable to set busy ! WSTATE sem is allready 0 !!!");
654
+		_worker_idle = 0;
655
+		kill(PyFCGI_conf.context.ppid, SIGTERM);
656
+		kill(PyFCGI_conf.context.pid, SIGTERM);
633 657
 		return;
634 658
 	}
635 659
 	_worker_idle = 0;

+ 11
- 0
src/stats.c View File

@@ -73,6 +73,17 @@ void pyfcgi_stats_collector(int signum)
73 73
 	stats->reqs.samples[stats->reqs.cur] = 0;
74 74
 	while( !(ret = sem_trywait(PyFCGI_SEM(SEM_WREQS).sem)) )
75 75
 	{
76
+		if(ret < 0)
77
+		{
78
+			pyfcgi_IPC_close(IPC_WREQS);
79
+			if(pyfcgi_IPC_init(IPC_WREQS))
80
+			{
81
+				pyfcgi_log(LOG_ALERT,
82
+					"Unable to gain access again to IPC_WREQS, exiting...");
83
+				kill(PyFCGI_conf.context.pid, SIGTERM);
84
+			}
85
+			continue;
86
+		}
76 87
 		stats->reqs.samples[stats->reqs.cur]++;
77 88
 	}
78 89
 	stats->reqs.cur++;

Loading…
Cancel
Save