7011441: jndi/ldap/Connection.java needs to avoid spurious wakeup
authorigerasim
Sat, 30 May 2015 15:19:15 +0300
changeset 30901 3a319ea18158
parent 30900 bef45ee9a95e
child 30902 cf3d869e9f79
7011441: jndi/ldap/Connection.java needs to avoid spurious wakeup Reviewed-by: dholmes
jdk/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java
--- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 29 15:17:07 2015 -0400
+++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java	Sat May 30 15:19:15 2015 +0300
@@ -393,9 +393,14 @@
     BerDecoder readReply(LdapRequest ldr)
             throws IOException, NamingException {
         BerDecoder rber;
-        boolean waited = false;
 
-        while (((rber = ldr.getReplyBer()) == null) && !waited) {
+        // Track down elapsed time to workaround spurious wakeups
+        long elapsedMilli = 0;
+        long elapsedNano = 0;
+
+        while (((rber = ldr.getReplyBer()) == null) &&
+                (readTimeout <= 0 || elapsedMilli < readTimeout))
+        {
             try {
                 // If socket closed, don't even try
                 synchronized (this) {
@@ -409,11 +414,15 @@
                     rber = ldr.getReplyBer();
                     if (rber == null) {
                         if (readTimeout > 0) {  // Socket read timeout is specified
+                            long beginNano = System.nanoTime();
 
-                            // will be woken up before readTimeout only if reply is
+                            // will be woken up before readTimeout if reply is
                             // available
-                            ldr.wait(readTimeout);
-                            waited = true;
+                            ldr.wait(readTimeout - elapsedMilli);
+                            elapsedNano += (System.nanoTime() - beginNano);
+                            elapsedMilli += elapsedNano / 1000_000;
+                            elapsedNano %= 1000_000;
+
                         } else {
                             // no timeout is set so we wait infinitely until
                             // a response is received
@@ -430,7 +439,7 @@
             }
         }
 
-        if ((rber == null) && waited) {
+        if ((rber == null) && (elapsedMilli >= readTimeout)) {
             abandonRequest(ldr, null);
             throw new NamingException("LDAP response read timed out, timeout used:"
                             + readTimeout + "ms." );