diff options
Diffstat (limited to 'socket_alive.c')
-rw-r--r-- | socket_alive.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/socket_alive.c b/socket_alive.c new file mode 100644 index 0000000..37e52a1 --- /dev/null +++ b/socket_alive.c @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012-2013, Eric Wong <normalperson@yhbt.net> + * License: GPLv3 or later (see COPYING for details) + */ +#include "cmogstored.h" + +/* + * check for POLLERR/POLLHUP on the socket to see if it died while + * we were in the queue. This can save us from expensive processing. + */ +bool mog_socket_alive(struct mog_fd *mfd) +{ + static const short dead_events = POLLERR | POLLHUP; + struct pollfd fds = { .fd = mfd->fd, .events = POLLIN }; + int rc; + int nbytes; + + do { + rc = poll(&fds, 1, 0); + } while (rc < 0 && errno == EINTR); + + if (rc == 1) { + if (fds.revents & POLLIN) { + CHECK(int, 0, ioctl(mfd->fd, FIONREAD, &nbytes)); + return (nbytes <= 0) ? false : true; + } + return (fds.revents & dead_events) ? false : true; + } + if (rc == 0) + return true; + + assert(rc < 0 && "poll returned unexpected value"); + + if (errno == ENOMEM || errno == EAGAIN) + return false; /* kernel is in trouble, abort */ + + assert(0 && "poll usage bug?"); + return false; +} |