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;