Skip to content

Commit 33bb201

Browse files
committed
Fix bug #76003: FPM /status reports wrong number of active processe
The fix introduces early locking of scoreboard when it is updated which prevents the race condition causing an incorrect number of active processes being set.
1 parent 07e91ca commit 33bb201

File tree

5 files changed

+66
-20
lines changed

5 files changed

+66
-20
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ PHP NEWS
66
. Fixed bug GH-8289 (Exceptions thrown within a yielded from iterator are
77
not rethrown into the generator). (Bob)
88

9+
- FPM:
10+
. Fixed bug #76003 (FPM /status reports wrong number of active processe).
11+
(Jakub Zelenka)
12+
913
- MySQLi:
1014
. Fixed bug GH-8267 (MySQLi uses unsupported format specifier on Windows).
1115
(cmb)

sapi/fpm/fpm/fpm_process_ctl.c

+19-16
Original file line numberDiff line numberDiff line change
@@ -324,21 +324,6 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
324324

325325
if (wp->config == NULL) continue;
326326

327-
for (child = wp->children; child; child = child->next) {
328-
if (fpm_request_is_idle(child)) {
329-
if (last_idle_child == NULL) {
330-
last_idle_child = child;
331-
} else {
332-
if (timercmp(&child->started, &last_idle_child->started, <)) {
333-
last_idle_child = child;
334-
}
335-
}
336-
idle++;
337-
} else {
338-
active++;
339-
}
340-
}
341-
342327
/* update status structure for all PMs */
343328
if (wp->listen_address_domain == FPM_AF_INET) {
344329
if (0 > fpm_socket_get_listening_queue(wp->listening_socket, &cur_lq, NULL)) {
@@ -356,7 +341,25 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
356341
#endif
357342
}
358343
}
359-
fpm_scoreboard_update(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
344+
345+
fpm_scoreboard_update_begin(wp->scoreboard);
346+
347+
for (child = wp->children; child; child = child->next) {
348+
if (fpm_request_is_idle(child)) {
349+
if (last_idle_child == NULL) {
350+
last_idle_child = child;
351+
} else {
352+
if (timercmp(&child->started, &last_idle_child->started, <)) {
353+
last_idle_child = child;
354+
}
355+
}
356+
idle++;
357+
} else {
358+
active++;
359+
}
360+
}
361+
362+
fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
360363

361364
/* this is specific to PM_STYLE_ONDEMAND */
362365
if (wp->config->pm == PM_STYLE_ONDEMAND) {

sapi/fpm/fpm/fpm_request.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ void fpm_request_accepting() /* {{{ */
4141

4242
fpm_clock_get(&now);
4343

44+
fpm_scoreboard_update_begin(NULL);
45+
4446
proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
4547
if (proc == NULL) {
4648
zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
@@ -52,7 +54,7 @@ void fpm_request_accepting() /* {{{ */
5254
fpm_scoreboard_proc_release(proc);
5355

5456
/* idle++, active-- */
55-
fpm_scoreboard_update(1, -1, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
57+
fpm_scoreboard_update_commit(1, -1, 0, 0, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
5658
}
5759
/* }}} */
5860

@@ -72,6 +74,8 @@ void fpm_request_reading_headers() /* {{{ */
7274
times(&cpu);
7375
#endif
7476

77+
fpm_scoreboard_update_begin(NULL);
78+
7579
proc = fpm_scoreboard_proc_acquire(NULL, -1, 0);
7680
if (proc == NULL) {
7781
zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
@@ -95,7 +99,7 @@ void fpm_request_reading_headers() /* {{{ */
9599
fpm_scoreboard_proc_release(proc);
96100

97101
/* idle--, active++, request++ */
98-
fpm_scoreboard_update(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
102+
fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
99103
}
100104
/* }}} */
101105

sapi/fpm/fpm/fpm_scoreboard.c

+34-2
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,39 @@ int fpm_scoreboard_init_main() /* {{{ */
7474
}
7575
/* }}} */
7676

77-
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
77+
static struct fpm_scoreboard_s *fpm_scoreboard_get_for_update(struct fpm_scoreboard_s *scoreboard) /* {{{ */
7878
{
7979
if (!scoreboard) {
8080
scoreboard = fpm_scoreboard;
8181
}
8282
if (!scoreboard) {
8383
zlog(ZLOG_WARNING, "Unable to update scoreboard: the SHM has not been found");
84-
return;
8584
}
8685

86+
return scoreboard;
87+
}
88+
/* }}} */
89+
90+
void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard) /* {{{ */
91+
{
92+
scoreboard = fpm_scoreboard_get_for_update(scoreboard);
93+
if (!scoreboard) {
94+
return;
95+
}
8796

8897
fpm_spinlock(&scoreboard->lock, 0);
98+
}
99+
/* }}} */
100+
101+
void fpm_scoreboard_update_commit(
102+
int idle, int active, int lq, int lq_len, int requests, int max_children_reached,
103+
int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
104+
{
105+
scoreboard = fpm_scoreboard_get_for_update(scoreboard);
106+
if (!scoreboard) {
107+
return;
108+
}
109+
89110
if (action == FPM_SCOREBOARD_ACTION_SET) {
90111
if (idle >= 0) {
91112
scoreboard->idle = idle;
@@ -154,6 +175,17 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request
154175
}
155176
/* }}} */
156177

178+
179+
void fpm_scoreboard_update(
180+
int idle, int active, int lq, int lq_len, int requests, int max_children_reached,
181+
int slow_rq, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
182+
{
183+
fpm_scoreboard_update_begin(scoreboard);
184+
fpm_scoreboard_update_commit(
185+
idle, active, lq, lq_len, requests, max_children_reached, slow_rq, action, scoreboard);
186+
}
187+
/* }}} */
188+
157189
struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
158190
{
159191
return fpm_scoreboard;

sapi/fpm/fpm/fpm_scoreboard.h

+3
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ struct fpm_scoreboard_s {
7373
int fpm_scoreboard_init_main();
7474
int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
7575

76+
void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard);
77+
void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
7678
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
79+
7780
struct fpm_scoreboard_s *fpm_scoreboard_get();
7881
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
7982
struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child);

0 commit comments

Comments
 (0)