8042857: 14 stuck threads waiting for notification on LDAPRequest
authorrobm
Fri, 23 May 2014 16:24:43 +0100
changeset 24519 2fab99d91c4d
parent 24518 c09ef49b5106
child 24567 a0ebe5fd56ff
8042857: 14 stuck threads waiting for notification on LDAPRequest Reviewed-by: vinnie
jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 23 16:35:10 2014 +0200
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java	Fri May 23 16:24:43 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -459,10 +459,10 @@
                             // will be woken up before readTimeout only if reply is
                             // available
                             ldr.wait(readTimeout);
-                            waited = true;
                         } else {
                             ldr.wait(15 * 1000); // 15 second timeout
                         }
+                        waited = true;
                     } else {
                         break;
                     }
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Fri May 23 16:35:10 2014 +0200
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java	Fri May 23 16:24:43 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,11 +64,12 @@
         env.put(Context.SECURITY_PRINCIPAL, "user");
         env.put(Context.SECURITY_CREDENTIALS, "password");
 
-        env.put("com.sun.jndi.ldap.connect.timeout", "10");
-        env.put("com.sun.jndi.ldap.read.timeout", "3000");
-
         InitialContext ctx = null;
         try {
+            new LdapTimeoutTest().deadServerNoTimeout(env);
+
+            env.put("com.sun.jndi.ldap.connect.timeout", "10");
+            env.put("com.sun.jndi.ldap.read.timeout", "3000");
             new LdapTimeoutTest().ldapReadTimeoutTest(env, false);
             new LdapTimeoutTest().ldapReadTimeoutTest(env, true);
             new LdapTimeoutTest().simpleAuthConnectTest(env);
@@ -84,7 +85,7 @@
     void ldapReadTimeoutTest(Hashtable env, boolean ssl) {
         InitialContext ctx = null;
         if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl");
-        ScheduledFuture killer = killSwitch();
+        ScheduledFuture killer = killSwitch(5000);
         long start = System.nanoTime();
         try {
             ctx = new InitialDirContext(env);
@@ -112,7 +113,7 @@
 
     void simpleAuthConnectTest(Hashtable env) {
         InitialContext ctx = null;
-        ScheduledFuture killer = killSwitch();
+        ScheduledFuture killer = killSwitch(5000);
         long start = System.nanoTime();
         try {
             ctx = new InitialDirContext(env);
@@ -139,6 +140,32 @@
         }
     }
 
+    void deadServerNoTimeout(Hashtable env) {
+        InitialContext ctx = null;
+        ScheduledFuture killer = killSwitch(30000);
+        long start = System.nanoTime();
+        try {
+            ctx = new InitialDirContext(env);
+            SearchControls scl = new SearchControls();
+            scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx)
+                .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
+            // shouldn't reach here
+            fail();
+        } catch (NamingException e) {
+            long end = System.nanoTime();
+            if (TimeUnit.NANOSECONDS.toMillis(end - start) < 14000) {
+                System.err.println("fail: timeout should be at least 15 seconds, actual time: "
+                                   + TimeUnit.NANOSECONDS.toMillis(end - start));
+                fail();
+            } else {
+                pass();
+            }
+        } finally {
+            if (!shutItDown(killer, ctx)) fail();
+        }
+    }
+
     boolean shutItDown(ScheduledFuture killer, InitialContext ctx) {
         killer.cancel(true);
         try {
@@ -149,15 +176,15 @@
         }
     }
 
-    ScheduledFuture killSwitch() {
+    ScheduledFuture killSwitch(int ms) {
         final Thread current = Thread.currentThread();
         return LdapTimeoutTest.pool.schedule(new Callable<Void>() {
             public Void call() throws Exception {
                 System.err.println("Fail: killSwitch()");
-                current.interrupt();
+                System.exit(0);
                 return null;
             }
-        }, 5000, TimeUnit.MILLISECONDS);
+        }, ms, TimeUnit.MILLISECONDS);
     }
 
     static class Server extends Thread {