Handle unexpected closing of child fds gracefully

This commit is contained in:
Kovid Goyal 2017-09-08 08:10:23 +05:30
parent 9b9003ded0
commit c97afd7b44
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -628,13 +628,14 @@ io_loop(void *data) {
for (i = 0; i < self->count + EXTRA_FDS; i++) fds[i].revents = 0; for (i = 0; i < self->count + EXTRA_FDS; i++) fds[i].revents = 0;
for (i = 0; i < self->count; i++) { for (i = 0; i < self->count; i++) {
screen = children[i].screen; screen = children[i].screen;
/* printf("i:%lu id:%lu fd: %d read_buf_sz: %lu write_buf_sz: %lu\n", i, children[i].id, children[i].fd, screen->read_buf_sz, screen->write_buf_sz); */
screen_mutex(lock, read); screen_mutex(lock, write); screen_mutex(lock, read); screen_mutex(lock, write);
fds[EXTRA_FDS + i].events = (screen->read_buf_sz < READ_BUF_SZ ? POLLIN : 0) | (screen->write_buf_sz ? POLLOUT : 0); fds[EXTRA_FDS + i].events = (screen->read_buf_sz < READ_BUF_SZ ? POLLIN : 0) | (screen->write_buf_sz ? POLLOUT : 0);
screen_mutex(unlock, read); screen_mutex(unlock, write); screen_mutex(unlock, read); screen_mutex(unlock, write);
} }
ret = poll(fds, self->count + EXTRA_FDS, -1); ret = poll(fds, self->count + EXTRA_FDS, -1);
if (ret > 0) { if (ret > 0) {
if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); if (fds[0].revents && POLLIN) drain_fd(fds[0].fd); // wakeup
if (fds[1].revents && POLLIN) { if (fds[1].revents && POLLIN) {
data_received = true; data_received = true;
drain_fd(fds[1].fd); drain_fd(fds[1].fd);
@ -656,6 +657,21 @@ io_loop(void *data) {
if (fds[EXTRA_FDS + i].revents & POLLOUT) { if (fds[EXTRA_FDS + i].revents & POLLOUT) {
write_to_child(children[i].fd, children[i].screen); write_to_child(children[i].fd, children[i].screen);
} }
if (fds[EXTRA_FDS + i].revents & POLLNVAL) {
// fd was closed
children_mutex(lock);
children[i].needs_removal = true;
children_mutex(unlock);
fprintf(stderr, "The child %lu had its fd unexpectedly closed\n", children[i].id);
}
}
if (false) {
for (i = 0; i < self->count + EXTRA_FDS; i++) {
#define P(w) if (fds[i].revents & w) printf("i:%lu %s\n", i, #w);
P(POLLIN); P(POLLPRI); P(POLLOUT); P(POLLRDHUP); P(POLLERR); P(POLLHUP); P(POLLNVAL);
#undef P
}
} }
} else if (ret < 0) { } else if (ret < 0) {
if (errno != EAGAIN && errno != EINTR) { if (errno != EAGAIN && errno != EINTR) {