--- old/src/share/classes/com/sun/jndi/ldap/Connection.java 2013-11-29 23:51:07.773225102 +0400 +++ new/src/share/classes/com/sun/jndi/ldap/Connection.java 2013-11-29 23:51:07.249231689 +0400 @@ -438,42 +438,51 @@ */ BerDecoder readReply(LdapRequest ldr) throws IOException, NamingException { - BerDecoder rber; - boolean waited = false; - while (((rber = ldr.getReplyBer()) == null) && !waited) { - try { - // If socket closed, don't even try - synchronized (this) { - if (sock == null) { - throw new ServiceUnavailableException(host + ":" + port + - "; socket closed"); - } + int timeOut = 15 * 1000; // Default read timeout of 15 sec + + if (readTimeout > 0) { + timeOut = readTimeout; // Specified read timeout + } + + long startTime = System.currentTimeMillis(); + + // Get the reply if it is already available. + BerDecoder rber = ldr.getReplyBer(); + + // Wait till we get a reply or read time out occurs. + while ((rber == null) && timeOut > 0) { + // If socket is already closed, no point to wait for the reply. + synchronized (this) { + if (sock == null) { + throw new ServiceUnavailableException(host + ":" + port + + "; socket closed"); } - synchronized (ldr) { - // check if condition has changed since our last check - rber = ldr.getReplyBer(); - if (rber == null) { - if (readTimeout > 0) { // Socket read timeout is specified - - // will be woken up before readTimeout only if reply is - // available - ldr.wait(readTimeout); - waited = true; - } else { - ldr.wait(15 * 1000); // 15 second timeout - } - } else { - break; + } + + long currTime = System.currentTimeMillis(); + if (startTime > currTime) { + // System time must have changed + startTime = currTime; + } + + if ((timeOut -= (currTime - startTime)) > 0) { + try { + synchronized (ldr) { + ldr.wait(timeOut); } + } catch (InterruptedException ex) { + throw new InterruptedNamingException( + "Interrupted during LDAP operation"); } - } catch (InterruptedException ex) { - throw new InterruptedNamingException( - "Interrupted during LDAP operation"); } + + rber = ldr.getReplyBer(); } - if ((rber == null) && waited) { + // Throw the time out exception only when time out is specified. Otherwise, + // return null if reply is not available. + if ((rber == null) && readTimeout > 0) { removeRequest(ldr); throw new NamingException("LDAP response read timed out, timeout used:" + readTimeout + "ms." );