You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2015/04/07 22:40:46 UTC
[2/2] thrift git commit: THRIFT-3080: fix connection leak of C++
Nonblocking Server while huge number connections are accepted and unix socket
stream fd is busy.
THRIFT-3080: fix connection leak of C++ Nonblocking Server while huge number connections are accepted and unix socket stream fd is busy.
Project: http://git-wip-us.apache.org/repos/asf/thrift/repo
Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/38772c9c
Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/38772c9c
Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/38772c9c
Branch: refs/heads/master
Commit: 38772c9c8d2eeb43fcf11ff2bff7729b8d76f431
Parents: 9226590
Author: abadcafe <fw...@live.com>
Authored: Fri Apr 3 22:23:04 2015 +0800
Committer: Roger Meier <ro...@apache.org>
Committed: Tue Apr 7 22:38:25 2015 +0200
----------------------------------------------------------------------
.../src/thrift/server/TNonblockingServer.cpp | 37 ++++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/thrift/blob/38772c9c/lib/cpp/src/thrift/server/TNonblockingServer.cpp
----------------------------------------------------------------------
diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.cpp b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
index 587560c..31bc34b 100644
--- a/lib/cpp/src/thrift/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
@@ -28,6 +28,7 @@
#include <thrift/transport/PlatformSocket.h>
#include <iostream>
+#include <poll.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -1393,9 +1394,39 @@ bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) {
return false;
}
- const int kSize = sizeof(conn);
- if (send(fd, const_cast_sockopt(&conn), kSize, 0) != kSize) {
- return false;
+ int ret = -1;
+ struct pollfd pfd = {fd, POLLOUT, 0};
+ int kSize = sizeof(conn);
+ const char * pos = (const char *)const_cast_sockopt(&conn);
+
+ while (kSize > 0) {
+ pfd.revents = 0;
+ ret = poll(&pfd, 1, -1);
+ if (ret < 0) {
+ return false;
+ } else if (ret == 0) {
+ continue;
+ }
+
+ if (pfd.revents & POLLHUP || pfd.revents & POLLERR) {
+ ::close(fd);
+ return false;
+ }
+
+ if (pfd.revents & POLLOUT) {
+ ret = send(fd, pos, kSize, 0);
+ if (ret < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ }
+
+ ::close(fd);
+ return false;
+ }
+
+ kSize -= ret;
+ pos += ret;
+ }
}
return true;