From 1e20ee99a382c5a1cfaea72da495951e83b777a8 Mon Sep 17 00:00:00 2001 From: MOON_CLJ Date: Mon, 29 Jan 2018 16:34:23 +0800 Subject: [PATCH] use getsockopt to check connection state after poll indicate writable --- src/Connection.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Connection.cpp b/src/Connection.cpp index 70837dcf..8fd47b2f 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -69,6 +69,7 @@ int Connection::connect() { if (server_addrinfo) { freeaddrinfo(server_addrinfo); } + log_warn("[I: %p] %s getaddrinfo err", this, m_name); return -1; } @@ -134,23 +135,44 @@ int Connection::connectPoll(int fd, struct addrinfo* ai_ptr) { pollfd_t pollfds[n_fds]; pollfds[0].fd = fd; pollfds[0].events = POLLOUT; + // clean errno + errno = 0; int max_timeout = 6; while (--max_timeout) { - int rv = poll(pollfds, n_fds, m_connectTimeout); + rv = poll(pollfds, n_fds, m_connectTimeout); if (rv == 1) { if (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { + log_warn("[I: %p] %s conn poll err", this, m_name); return -1; } else { + int err = 0; + socklen_t errlen = sizeof(err); + + if (::getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) { + log_warn("[I: %p] %s getsockopt err", this, m_name); + return -1; + } + + if (err) { + errno = err; + log_warn("[I: %p] %s getsockopt indicate connect err", this, m_name); + return -1; + } return 0; } } else if (rv == -1) { + log_warn("[I: %p] %s poll err", this, m_name); return -1; } } + log_warn("[I: %p] %s connect timeout after poll retry", this, m_name); return -1; } default: - return -1; + { + log_warn("[I: %p] %s connect err", this, m_name); + return -1; + } } }