Skip to content

Commit 2e97d47

Browse files
committed
FPM: Postpone child freeing in event loop
This is to prevent after free accessing of the child event that might happen when child is killed and the message is delivered at that same time.
1 parent 4be6435 commit 2e97d47

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

sapi/fpm/fpm/fpm_children.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,29 @@ static void fpm_child_free(struct fpm_child_s *child) /* {{{ */
6363
}
6464
/* }}} */
6565

66+
static void fpm_postponed_child_free(struct fpm_event_s *ev, short which, void *arg)
67+
{
68+
struct fpm_child_s *child = (struct fpm_child_s *) arg;
69+
70+
if (child->fd_stdout != -1) {
71+
fpm_event_del(&child->ev_stdout);
72+
close(child->fd_stdout);
73+
}
74+
if (child->fd_stderr != -1) {
75+
fpm_event_del(&child->ev_stderr);
76+
close(child->fd_stderr);
77+
}
78+
79+
fpm_child_free((struct fpm_child_s *) child);
80+
}
81+
6682
static void fpm_child_close(struct fpm_child_s *child, int in_event_loop) /* {{{ */
6783
{
84+
bool postponed_free = false;
6885
if (child->fd_stdout != -1) {
6986
if (in_event_loop) {
7087
fpm_event_fire(&child->ev_stdout);
88+
postponed_free = true;
7189
}
7290
if (child->fd_stdout != -1) {
7391
close(child->fd_stdout);
@@ -77,13 +95,19 @@ static void fpm_child_close(struct fpm_child_s *child, int in_event_loop) /* {{{
7795
if (child->fd_stderr != -1) {
7896
if (in_event_loop) {
7997
fpm_event_fire(&child->ev_stderr);
98+
postponed_free = true;
8099
}
81100
if (child->fd_stderr != -1) {
82101
close(child->fd_stderr);
83102
}
84103
}
85104

86-
fpm_child_free(child);
105+
if (postponed_free) {
106+
fpm_event_set_timer(&child->ev_free, 0, &fpm_postponed_child_free, child);
107+
fpm_event_add(&child->ev_free, 1000);
108+
} else {
109+
fpm_child_free(child);
110+
}
87111
}
88112
/* }}} */
89113

sapi/fpm/fpm/fpm_children.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ struct fpm_child_s {
2323
struct fpm_child_s *prev, *next;
2424
struct timeval started;
2525
struct fpm_worker_pool_s *wp;
26-
struct fpm_event_s ev_stdout, ev_stderr;
26+
struct fpm_event_s ev_stdout, ev_stderr, ev_free;
2727
int shm_slot_i;
2828
int fd_stdout, fd_stderr;
2929
void (*tracer)(struct fpm_child_s *);
3030
struct timeval slow_logged;
31-
int idle_kill;
31+
bool idle_kill;
32+
bool burried;
3233
pid_t pid;
3334
int scoreboard_i;
3435
struct zlog_stream *log_stream;

sapi/fpm/fpm/fpm_stdio.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,7 @@ static void fpm_stdio_child_said(struct fpm_event_s *ev, short which, void *arg)
181181
if (!arg) {
182182
return;
183183
}
184-
child = fpm_child_find((intptr_t) arg);
185-
if (!child) {
186-
return;
187-
}
184+
child = (struct fpm_child_s *) arg;
188185

189186
is_stdout = (fd == child->fd_stdout);
190187
if (is_stdout) {
@@ -330,10 +327,10 @@ int fpm_stdio_parent_use_pipes(struct fpm_child_s *child) /* {{{ */
330327
child->fd_stdout = fd_stdout[0];
331328
child->fd_stderr = fd_stderr[0];
332329

333-
fpm_event_set(&child->ev_stdout, child->fd_stdout, FPM_EV_READ, fpm_stdio_child_said, (void *) (intptr_t) child->pid);
330+
fpm_event_set(&child->ev_stdout, child->fd_stdout, FPM_EV_READ, fpm_stdio_child_said, child);
334331
fpm_event_add(&child->ev_stdout, 0);
335332

336-
fpm_event_set(&child->ev_stderr, child->fd_stderr, FPM_EV_READ, fpm_stdio_child_said, (void *) (intptr_t) child->pid);
333+
fpm_event_set(&child->ev_stderr, child->fd_stderr, FPM_EV_READ, fpm_stdio_child_said, child);
337334
fpm_event_add(&child->ev_stderr, 0);
338335
return 0;
339336
}

0 commit comments

Comments
 (0)