提交 d30b0094 编写于 作者: R robm

8169465: Deadlock in com.sun.jndi.ldap.pool.Connections

Reviewed-by: dfuchs, vtewari
上级 a7e89a59
...@@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool; ...@@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool;
import java.util.ArrayList; // JDK 1.2 import java.util.ArrayList; // JDK 1.2
import java.util.List; import java.util.List;
import java.util.Iterator;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
...@@ -290,23 +289,28 @@ final class Connections implements PoolCallback { ...@@ -290,23 +289,28 @@ final class Connections implements PoolCallback {
* @param threshold an entry idle since this time has expired. * @param threshold an entry idle since this time has expired.
* @return true if no more connections in list * @return true if no more connections in list
*/ */
synchronized boolean expire(long threshold) { boolean expire(long threshold) {
Iterator<ConnectionDesc> iter = conns.iterator(); List<ConnectionDesc> clonedConns;
ConnectionDesc entry; synchronized(this) {
while (iter.hasNext()) { clonedConns = new ArrayList<>(conns);
entry = iter.next(); }
if (entry.expire(threshold)) { List<ConnectionDesc> expired = new ArrayList<>();
d("expire(): removing ", entry);
td("Expired ", entry);
iter.remove(); // remove from pool
// Don't need to call notify() because we're for (ConnectionDesc entry : clonedConns) {
// removing only idle connections. If there were d("expire(): ", entry);
// idle connections, then there should be no waiters. if (entry.expire(threshold)) {
expired.add(entry);
td("expire(): Expired ", entry);
} }
} }
return conns.isEmpty(); // whether whole list has 'expired'
synchronized (this) {
conns.removeAll(expired);
// Don't need to call notify() because we're
// removing only idle connections. If there were
// idle connections, then there should be no waiters.
return conns.isEmpty(); // whether whole list has 'expired'
}
} }
/** /**
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
package com.sun.jndi.ldap.pool; package com.sun.jndi.ldap.pool;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.io.PrintStream; import java.io.PrintStream;
...@@ -166,17 +166,25 @@ final public class Pool { ...@@ -166,17 +166,25 @@ final public class Pool {
* and removed. * and removed.
*/ */
public void expire(long threshold) { public void expire(long threshold) {
Collection<ConnectionsRef> copy;
synchronized (map) { synchronized (map) {
Iterator<ConnectionsRef> iter = map.values().iterator(); copy = new ArrayList<>(map.values());
Connections conns; }
while (iter.hasNext()) {
conns = iter.next().getConnections(); ArrayList<ConnectionsRef> removed = new ArrayList<>();
if (conns.expire(threshold)) { Connections conns;
d("expire(): removing ", conns); for (ConnectionsRef ref : copy) {
iter.remove(); conns = ref.getConnections();
} if (conns.expire(threshold)) {
d("expire(): removing ", conns);
removed.add(ref);
} }
} }
synchronized (map) {
map.values().removeAll(removed);
}
expungeStaleConnections(); expungeStaleConnections();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册