Browse Source

Check for errors in wait_read_select, closing the socket if they occur, and add a variant for non-unix sockets that checks for hangups as well

master
Con Kolivas 9 years ago
parent
commit
b622a6ec8d
  1. 2
      src/ckpool.c
  2. 4
      src/generator.c
  3. 38
      src/libckpool.c
  4. 5
      src/libckpool.h

2
src/ckpool.c

@ -527,7 +527,7 @@ rewait:
ret = 0;
goto out;
}
ret = wait_read_select(cs->fd, eom ? 0 : *timeout);
ret = wait_recv_select(cs->fd, eom ? 0 : *timeout);
if (ret < 1) {
if (!ret) {
if (eom)

4
src/generator.c

@ -290,7 +290,7 @@ retry:
ckmsgq_add(gdata->srvchk, si);
do {
selret = wait_read_select(us->sockd, 5);
selret = wait_recv_select(us->sockd, 5);
if (!selret && !ping_main(ckp)) {
LOGEMERG("Generator failed to ping main process, exiting");
ret = 1;
@ -1632,7 +1632,7 @@ retry:
ckmsgq_add(gdata->srvchk, proxi->si);
do {
selret = wait_read_select(us->sockd, 5);
selret = wait_recv_select(us->sockd, 5);
if (!selret && !ping_main(ckp)) {
LOGEMERG("Generator failed to ping main process, exiting");
ret = 1;

38
src/libckpool.c

@ -758,17 +758,15 @@ out:
void empty_socket(int fd)
{
char buf[PAGESIZE];
int ret;
if (fd < 1)
return;
do {
char buf[PAGESIZE];
ret = wait_read_select(fd, 0);
ret = recv(fd, buf, PAGESIZE - 1, MSG_DONTWAIT);
if (ret > 0) {
ret = recv(fd, buf, PAGESIZE - 1, 0);
buf[ret] = 0;
LOGDEBUG("Discarding: %s", buf);
}
@ -907,21 +905,39 @@ int wait_close(int sockd, int timeout)
return sfd.revents & (POLLHUP | POLLRDHUP | POLLERR);
}
/* Emulate a select read wait for high fds that select doesn't support */
int wait_read_select(int sockd, float timeout)
/* Emulate a select read wait for high fds that select doesn't support.
* wait_read_select is for unix sockets and _wait_recv_select for regular
* sockets. */
int _wait_read_select(int *sockd, float timeout)
{
struct pollfd sfd;
int ret = -1;
if (unlikely(sockd < 0))
if (unlikely(*sockd < 0))
goto out;
sfd.fd = sockd;
sfd.fd = *sockd;
sfd.events = POLLIN | POLLRDHUP;
sfd.revents = 0;
timeout *= 1000;
ret = poll(&sfd, 1, timeout);
if (ret && !(sfd.revents & POLLIN))
ret = -1;
if (ret > 0 && sfd.revents & (POLLERR))
_Close(sockd);
out:
return ret;
}
int _wait_recv_select(int *sockd, float timeout)
{
struct pollfd sfd;
int ret = -1;
if (unlikely(*sockd < 0))
goto out;
sfd.fd = *sockd;
sfd.events = POLLIN | POLLRDHUP;
timeout *= 1000;
ret = poll(&sfd, 1, timeout);
if (ret > 0 && sfd.revents & (POLLHUP | POLLRDHUP | POLLERR))
_Close(sockd);
out:
return ret;
}

5
src/libckpool.h

@ -496,7 +496,10 @@ int _open_unix_server(const char *server_path, const char *file, const char *fun
int _open_unix_client(const char *server_path, const char *file, const char *func, const int line);
#define open_unix_client(server_path) _open_unix_client(server_path, __FILE__, __func__, __LINE__)
int wait_close(int sockd, int timeout);
int wait_read_select(int sockd, float timeout);
int _wait_read_select(int *sockd, float timeout);
#define wait_read_select(SOCKD, TIMEOUT) _wait_read_select(&(SOCKD), TIMEOUT)
int _wait_recv_select(int *sockd, float timeout);
#define wait_recv_select(SOCKD, TIMEOUT) _wait_recv_select(&(SOCKD), TIMEOUT)
int read_length(int sockd, void *buf, int len);
char *_recv_unix_msg(int sockd, int timeout1, int timeout2, const char *file, const char *func, const int line);
#define RECV_UNIX_TIMEOUT1 30

Loading…
Cancel
Save