changeset 10792:e62f6298008c

7011441: jndi/ldap/Connection.java needs to avoid spurious wakeup Reviewed-by: dholmes
author igerasim
date Sat, 30 May 2015 15:19:15 +0300
parents 9fb6ca49eacb
children c716a8cc3454
files src/share/classes/com/sun/jndi/ldap/Connection.java
diffstat 1 files changed, 15 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 29 17:27:55 2015 +0300
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java	Sat May 30 15:19:15 2015 +0300
@@ -439,9 +439,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) {
@@ -455,11 +460,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
@@ -476,7 +485,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." );