Ver código fonte

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 5 anos atrás
pai
commit
9a01ba69b9
2 arquivos alterados com 45 adições e 10 exclusões
  1. 34
    10
      src/pyworker.c
  2. 11
    0
      src/stats.c

+ 34
- 10
src/pyworker.c Ver arquivo

610
 static void worker_set_busy()
610
 static void worker_set_busy()
611
 {
611
 {
612
 	int err;
612
 	int err;
613
+	short retry;
614
+	struct timespec timeout;
615
+	timeout.tv_sec = 0;
616
+	timeout.tv_nsec = 100000; //0.0001s
617
+
613
 	if(!_worker_idle) { return; }
618
 	if(!_worker_idle) { return; }
614
 	/**@todo The pool handler WILL decrement the sem to figure if the pool
619
 	/**@todo The pool handler WILL decrement the sem to figure if the pool
615
 	 * is busy -__- Using sem_wait make sure that the worker will be able
620
 	 * is busy -__- Using sem_wait make sure that the worker will be able
618
 	 * maybe to nanosleep 0.01s and retry a sem_trywait... SysV sem are
623
 	 * maybe to nanosleep 0.01s and retry a sem_trywait... SysV sem are
619
 	 * better T_T
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
 		return;
657
 		return;
634
 	}
658
 	}
635
 	_worker_idle = 0;
659
 	_worker_idle = 0;

+ 11
- 0
src/stats.c Ver arquivo

73
 	stats->reqs.samples[stats->reqs.cur] = 0;
73
 	stats->reqs.samples[stats->reqs.cur] = 0;
74
 	while( !(ret = sem_trywait(PyFCGI_SEM(SEM_WREQS).sem)) )
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
 		stats->reqs.samples[stats->reqs.cur]++;
87
 		stats->reqs.samples[stats->reqs.cur]++;
77
 	}
88
 	}
78
 	stats->reqs.cur++;
89
 	stats->reqs.cur++;

Carregando…
Cancelar
Salvar