From 8bb50fa05861aa2dfac08001aac0839e057f4543 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 24 Apr 2015 15:04:41 +1000 Subject: [PATCH] Process epoll read messages before hangups and errors and add more info about the type of hang up, increasing verbosity when it's an unexpected error --- src/connector.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/connector.c b/src/connector.c index b141f205..44dbc76d 100644 --- a/src/connector.c +++ b/src/connector.c @@ -494,12 +494,34 @@ void *receiver(void *arg) LOGWARNING("Failed to find client by id in receiver!"); continue; } - if (event.events & (EPOLLERR | EPOLLHUP | EPOLLRDHUP)) { - /* Client disconnected */ - LOGDEBUG("Client fd %d HUP in epoll", client->fd); - invalidate_client(cdata->pi->ckp, cdata, client); - } else + /* We can have both messages and read hang ups so process the + * message first. */ + if (likely(event.events & EPOLLIN)) parse_client_msg(cdata, client); + if (unlikely(event.events & EPOLLERR)) { + socklen_t errlen = sizeof(int); + int error = 0; + + /* See what type of error this is and raise the log + * level of the message if it's unexpected. */ + getsockopt(client->fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen); + if (error != 104) { + LOGNOTICE("Client id %"PRId64" fd %d epollerr HUP in epoll with error %d: %s", + client->id, client->fd, error, strerror(error)); + } else { + LOGINFO("Client id %"PRId64" fd %d epollerr HUP in epoll with error %d: %s", + client->id, client->fd, error, strerror(error)); + } + invalidate_client(cdata->pi->ckp, cdata, client); + } else if (unlikely(event.events & EPOLLHUP)) { + /* Client connection reset by peer */ + LOGINFO("Client id %"PRId64" fd %d HUP in epoll", client->id, client->fd); + invalidate_client(cdata->pi->ckp, cdata, client); + } else if (unlikely(event.events & EPOLLRDHUP)) { + /* Client disconnected by peer */ + LOGINFO("Client id %"PRId64" fd %d RDHUP in epoll", client->id, client->fd); + invalidate_client(cdata->pi->ckp, cdata, client); + } dec_instance_ref(cdata, client); } return NULL;