use poll instead of select in TSocket
Summary: fd_set, which we pass into select only supports fds with values < 1024.
fds can be >= 1024.
this can cause memory corruption
learning this stuff over 2 weeks of examining crazy core dumps is way more fun that reading it up somewhere.
poll takes an array of fds insetad, so your fd can be any int
Reviewed By: dreiss
Test Plan: ran inside a test search cluster
Revert: OK
DiffCamp Revision: 10731
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665647 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TSocket.cpp b/lib/cpp/src/transport/TSocket.cpp
index c216929..85a6358 100644
--- a/lib/cpp/src/transport/TSocket.cpp
+++ b/lib/cpp/src/transport/TSocket.cpp
@@ -6,7 +6,7 @@
#include <config.h>
#include <sys/socket.h>
-#include <sys/select.h>
+#include <sys/poll.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -142,10 +142,6 @@
}
}
- // Conn timeout
- struct timeval c = {(int)(connTimeout_/1000),
- (int)((connTimeout_%1000)*1000)};
-
// Connect the socket
int ret = connect(socket_, res->ai_addr, res->ai_addrlen);
@@ -160,10 +156,12 @@
throw TTransportException(TTransportException::NOT_OPEN, "connect()", errno_copy);
}
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(socket_, &fds);
- ret = select(socket_+1, NULL, &fds, NULL, &c);
+
+ struct pollfd fds[1];
+ memset(fds, 0 , sizeof(fds));
+ fds[0].fd = socket_;
+ fds[0].events = POLLOUT;
+ ret = poll(fds, 1, connTimeout_);
if (ret > 0) {
// Ensure connected
@@ -191,7 +189,7 @@
throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
} else {
int errno_copy = errno;
- string errStr = "TSocket::open() select error " + getSocketInfo();
+ string errStr = "TSocket::open() poll error " + getSocketInfo();
GlobalOutput(errStr.c_str());
throw TTransportException(TTransportException::NOT_OPEN, "open()", errno_copy);
}
@@ -453,7 +451,7 @@
recvTimeval_.tv_sec = (int)(recvTimeout_/1000);
recvTimeval_.tv_usec = (int)((recvTimeout_%1000)*1000);
- // Copy because select may modify
+ // Copy because poll may modify
struct timeval r = recvTimeval_;
int ret = setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, &r, sizeof(r));
if (ret == -1) {