Browse Source

HADOOP-2971. select multiple times if it returns early in
SocketIOWithTimeout. (rangadi)


git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/trunk@635792 13f79535-47bb-0310-9956-ffa450edef68

Raghu Angadi 17 years ago
parent
commit
4ab9ef439c
2 changed files with 26 additions and 21 deletions
  1. 3 0
      CHANGES.txt
  2. 23 21
      src/java/org/apache/hadoop/net/SocketIOWithTimeout.java

+ 3 - 0
CHANGES.txt

@@ -167,6 +167,9 @@ Trunk (unreleased changes)
     HADOOP-2973. Fix TestLocalDFS for Windows platform.
     (Tsz Wo (Nicholas), SZE via dhruba)
 
+    HADOOP-2971. select multiple times if it returns early in 
+    SocketIOWithTimeout. (rangadi)
+
 Release 0.16.1 - 2008-03-13
 
   INCOMPATIBLE CHANGES

+ 23 - 21
src/java/org/apache/hadoop/net/SocketIOWithTimeout.java

@@ -163,20 +163,6 @@ abstract class SocketIOWithTimeout {
       } 
 
       if (count == 0) {
-        String channelStr = "Unknown Channel";
-        if (channel instanceof SocketChannel) {
-          Socket sock = ((SocketChannel)channel).socket();
-          SocketAddress remote = sock.getRemoteSocketAddress();
-          SocketAddress local = sock.getLocalSocketAddress();
-          channelStr =  (remote == null ? "Unknown Addr" : remote) +
-                         " (local: " + 
-                         (local == null ? "Unknown Addr" : local) + ")";
-        } else if (channel instanceof Pipe.SinkChannel ||
-                   channel instanceof Pipe.SourceChannel) {
-          channelStr = "pipe";
-        } else if (channel instanceof DatagramChannel) {
-          channelStr = "datagram channel";
-        }
         
         String waitingFor = ""+ops;
         if (ops == SelectionKey.OP_READ) {
@@ -186,8 +172,8 @@ abstract class SocketIOWithTimeout {
         }
         
         throw new SocketTimeoutException(timeout + " millis timeout while " +
-                                         "waiting for " + channelStr +
-                                         " to be ready for " + waitingFor);
+                                         "waiting for channel to be ready for "
+                                         + waitingFor + ". ch : " + channel);
       }
       // otherwise the socket should be ready for io.
     }
@@ -245,11 +231,29 @@ abstract class SocketIOWithTimeout {
       SelectorInfo info = get(channel);
       
       SelectionKey key = null;
-      int ret = -1;
+      int ret = 0;
       
       try {
-        key = channel.register(info.selector, ops);
-        ret = info.selector.select(timeout);
+        while (true) {
+          long start = (timeout == 0) ? 0 : System.currentTimeMillis();
+
+          key = channel.register(info.selector, ops);
+          ret = info.selector.select(timeout);
+          
+          if (ret != 0) {
+            return ret;
+          }
+          
+          /* Sometimes select() returns 0 much before timeout for 
+           * unknown reasons. So select again if required.
+           */
+          if (timeout > 0) {
+            timeout -= System.currentTimeMillis() - start;
+            if (timeout <= 0) {
+              return 0;
+            }
+          }
+        }
       } finally {
         if (key != null) {
           key.cancel();
@@ -268,8 +272,6 @@ abstract class SocketIOWithTimeout {
         
         release(info);
       }
-      
-      return ret;
     }
     
     /**