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; ret = 0;
goto out; 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 < 1) {
if (!ret) { if (!ret) {
if (eom) if (eom)

4
src/generator.c

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

38
src/libckpool.c

@ -758,17 +758,15 @@ out:
void empty_socket(int fd) void empty_socket(int fd)
{ {
char buf[PAGESIZE];
int ret; int ret;
if (fd < 1) if (fd < 1)
return; return;
do { do {
char buf[PAGESIZE]; ret = recv(fd, buf, PAGESIZE - 1, MSG_DONTWAIT);
ret = wait_read_select(fd, 0);
if (ret > 0) { if (ret > 0) {
ret = recv(fd, buf, PAGESIZE - 1, 0);
buf[ret] = 0; buf[ret] = 0;
LOGDEBUG("Discarding: %s", buf); LOGDEBUG("Discarding: %s", buf);
} }
@ -907,21 +905,39 @@ int wait_close(int sockd, int timeout)
return sfd.revents & (POLLHUP | POLLRDHUP | POLLERR); return sfd.revents & (POLLHUP | POLLRDHUP | POLLERR);
} }
/* Emulate a select read wait for high fds that select doesn't support */ /* Emulate a select read wait for high fds that select doesn't support.
int wait_read_select(int sockd, float timeout) * 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; struct pollfd sfd;
int ret = -1; int ret = -1;
if (unlikely(sockd < 0)) if (unlikely(*sockd < 0))
goto out; goto out;
sfd.fd = sockd; sfd.fd = *sockd;
sfd.events = POLLIN | POLLRDHUP; sfd.events = POLLIN | POLLRDHUP;
sfd.revents = 0;
timeout *= 1000; timeout *= 1000;
ret = poll(&sfd, 1, timeout); ret = poll(&sfd, 1, timeout);
if (ret && !(sfd.revents & POLLIN)) if (ret > 0 && sfd.revents & (POLLERR))
ret = -1; _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: out:
return ret; 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); 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__) #define open_unix_client(server_path) _open_unix_client(server_path, __FILE__, __func__, __LINE__)
int wait_close(int sockd, int timeout); 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); 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); char *_recv_unix_msg(int sockd, int timeout1, int timeout2, const char *file, const char *func, const int line);
#define RECV_UNIX_TIMEOUT1 30 #define RECV_UNIX_TIMEOUT1 30

Loading…
Cancel
Save