# HG changeset patch
# User michaelm
# Date 1299172573 0
# Node ID 7b224edc9990ce04eaed1bb14568e68aa2f828da
# Parent e2df5f8fa0828804537efed57294153ada3e109d# Parent 460a150e05af7f3e0006f4876e4eb1029ae1d0ee
Merge
diff -r e2df5f8fa082 -r 7b224edc9990 jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Thu Mar 03 17:14:23 2011 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Thu Mar 03 17:16:13 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -380,13 +380,19 @@
}
LdapRequest writeRequest(BerEncoder ber, int msgId) throws IOException {
- return writeRequest(ber, msgId, false /* pauseAfterReceipt */);
+ return writeRequest(ber, msgId, false /* pauseAfterReceipt */, -1);
}
- LdapRequest writeRequest(BerEncoder ber, int msgId, boolean pauseAfterReceipt)
- throws IOException {
+ LdapRequest writeRequest(BerEncoder ber, int msgId,
+ boolean pauseAfterReceipt) throws IOException {
+ return writeRequest(ber, msgId, pauseAfterReceipt, -1);
+ }
- LdapRequest req = new LdapRequest(msgId, pauseAfterReceipt);
+ LdapRequest writeRequest(BerEncoder ber, int msgId,
+ boolean pauseAfterReceipt, int replyQueueCapacity) throws IOException {
+
+ LdapRequest req =
+ new LdapRequest(msgId, pauseAfterReceipt, replyQueueCapacity);
addRequest(req);
if (traceFile != null) {
diff -r e2df5f8fa082 -r 7b224edc9990 jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java Thu Mar 03 17:14:23 2011 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java Thu Mar 03 17:16:13 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -516,7 +516,8 @@
LdapResult search(String dn, int scope, int deref, int sizeLimit,
int timeLimit, boolean attrsOnly, String attrs[],
String filter, int batchSize, Control[] reqCtls,
- Hashtable binaryAttrs, boolean waitFirstReply)
+ Hashtable binaryAttrs, boolean waitFirstReply,
+ int replyQueueCapacity)
throws IOException, NamingException {
ensureOpen();
@@ -543,7 +544,8 @@
if (isLdapv3) encodeControls(ber, reqCtls);
ber.endSeq();
- LdapRequest req = conn.writeRequest(ber, curMsgId);
+ LdapRequest req =
+ conn.writeRequest(ber, curMsgId, false, replyQueueCapacity);
res.msgId = curMsgId;
res.status = LdapClient.LDAP_SUCCESS; //optimistic
diff -r e2df5f8fa082 -r 7b224edc9990 jdk/src/share/classes/com/sun/jndi/ldap/LdapCtx.java
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtx.java Thu Mar 03 17:14:23 2011 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtx.java Thu Mar 03 17:16:13 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -191,6 +191,14 @@
// Environment property for the domain name (derived from this context's DN)
private static final String DOMAIN_NAME = "com.sun.jndi.ldap.domainname";
+ // Block until the first search reply is received
+ private static final String WAIT_FOR_REPLY =
+ "com.sun.jndi.ldap.search.waitForReply";
+
+ // Size of the queue of unprocessed search replies
+ private static final String REPLY_QUEUE_SIZE =
+ "com.sun.jndi.ldap.search.replyQueueSize";
+
// ----------------- Fields that don't change -----------------------
private static final NameParser parser = new LdapNameParser();
@@ -246,6 +254,8 @@
private Hashtable binaryAttrs = null; // attr values returned as byte[]
private int connectTimeout = -1; // no timeout value
private int readTimeout = -1; // no timeout value
+ private boolean waitForReply = true; // wait for search response
+ private int replyQueueSize = -1; // unlimited queue size
private boolean useSsl = false; // true if SSL protocol is active
private boolean useDefaultPortNumber = false; // no port number was supplied
@@ -1759,8 +1769,8 @@
SearchControls cons,
Continuation cont)
throws NamingException {
- return searchAux(name, filter, cloneSearchControls(cons), true, true,
- cont);
+ return searchAux(name, filter, cloneSearchControls(cons), true,
+ waitForReply, cont);
}
protected NamingEnumeration c_search(Name name,
@@ -1928,7 +1938,7 @@
}
private LdapResult doSearch(Name name, String filter, SearchControls cons,
- boolean relative, boolean waitFirstReply) throws NamingException {
+ boolean relative, boolean waitForReply) throws NamingException {
ensureOpen();
try {
int scope;
@@ -1984,7 +1994,8 @@
batchSize,
reqCtls,
binaryAttrs,
- waitFirstReply);
+ waitForReply,
+ replyQueueSize);
respCtls = answer.resControls; // retrieve response controls
return answer;
@@ -2170,6 +2181,10 @@
connectTimeout = -1;
} else if (propName.equals(READ_TIMEOUT)) {
readTimeout = -1;
+ } else if (propName.equals(WAIT_FOR_REPLY)) {
+ waitForReply = true;
+ } else if (propName.equals(REPLY_QUEUE_SIZE)) {
+ replyQueueSize = -1;
// The following properties affect the connection
@@ -2225,6 +2240,11 @@
setConnectTimeout((String)propVal);
} else if (propName.equals(READ_TIMEOUT)) {
setReadTimeout((String)propVal);
+ } else if (propName.equals(WAIT_FOR_REPLY)) {
+ setWaitForReply((String)propVal);
+ } else if (propName.equals(REPLY_QUEUE_SIZE)) {
+ setReplyQueueSize((String)propVal);
+
// The following properties affect the connection
} else if (propName.equals(Context.SECURITY_PROTOCOL)) {
@@ -2312,6 +2332,13 @@
// Set the read timeout
setReadTimeout((String)envprops.get(READ_TIMEOUT));
+ // Set the flag that controls whether to block until the first reply
+ // is received
+ setWaitForReply((String)envprops.get(WAIT_FOR_REPLY));
+
+ // Set the size of the queue of unprocessed search replies
+ setReplyQueueSize((String)envprops.get(REPLY_QUEUE_SIZE));
+
// When connection is created, it will use these and other
// properties from the environment
}
@@ -2442,6 +2469,34 @@
}
/**
+ * Sets the size of the queue of unprocessed search replies
+ */
+ private void setReplyQueueSize(String replyQueueSizeProp) {
+ if (replyQueueSizeProp != null) {
+ replyQueueSize = Integer.parseInt(replyQueueSizeProp);
+ // disallow an empty queue
+ if (replyQueueSize <= 0) {
+ replyQueueSize = -1; // unlimited
+ }
+ } else {
+ replyQueueSize = -1; // unlimited
+ }
+ }
+
+ /**
+ * Sets the flag that controls whether to block until the first search
+ * reply is received
+ */
+ private void setWaitForReply(String waitForReplyProp) {
+ if (waitForReplyProp != null &&
+ (waitForReplyProp.equalsIgnoreCase("false"))) {
+ waitForReply = false;
+ } else {
+ waitForReply = true;
+ }
+ }
+
+ /**
* Sets the read timeout value
*/
private void setReadTimeout(String readTimeoutProp) {
diff -r e2df5f8fa082 -r 7b224edc9990 jdk/src/share/classes/com/sun/jndi/ldap/LdapRequest.java
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapRequest.java Thu Mar 03 17:14:23 2011 +0000
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapRequest.java Thu Mar 03 17:16:13 2011 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -26,7 +26,8 @@
package com.sun.jndi.ldap;
import java.io.IOException;
-import java.util.Vector;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import javax.naming.CommunicationException;
final class LdapRequest {
@@ -35,14 +36,26 @@
int msgId; // read-only
private int gotten = 0;
- private Vector replies = new Vector(3);
+ private BlockingQueue
Otherwise the new URI's authority component is copied from - * this URI, and its path is computed as follows:
Two hierarchical URIs with identical schemes are ordered - * according to the ordering of their authority components:
Finally, two hierarchical URIs with identical schemes and * authority components are ordered according to the ordering of their diff -r e2df5f8fa082 -r 7b224edc9990 jdk/src/share/classes/java/net/package.html --- a/jdk/src/share/classes/java/net/package.html Thu Mar 03 17:14:23 2011 +0000 +++ b/jdk/src/share/classes/java/net/package.html Thu Mar 03 17:16:13 2011 +0000 @@ -31,18 +31,18 @@
The java.net package can be roughly divided in two sections:
A Low Level API, which deals with the following abstractions:
A Low Level API, which deals with the following abstractions:
Addresses, which are networking identifiers, like IP addresses.
Sockets, which are basic bidirectional data communication mechanisms.
Interfaces, which describe network interfaces.
A High Level API, which deals with the following abstractions:
A High Level API, which deals with the following abstractions:
URIs, which represent Universal Resource Identifiers.
URLs, which represent Universal Resource Locators.
Connections, which represents connections to the resource pointed to by URLs.
Addresses are used throughout the java.net APIs as either host identifiers, or socket endpoint identifiers.
diff -r e2df5f8fa082 -r 7b224edc9990 jdk/test/com/sun/jndi/ldap/NoWaitForReplyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jndi/ldap/NoWaitForReplyTest.java Thu Mar 03 17:16:13 2011 +0000 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6748156 + * @summary add an new JNDI property to control the boolean flag WaitForReply + */ + +import java.net.Socket; +import java.net.ServerSocket; +import java.io.*; +import javax.naming.*; +import javax.naming.directory.*; +import java.util.Hashtable; + +public class NoWaitForReplyTest { + + public static void main(String[] args) throws Exception { + + boolean passed = false; + + // Set up the environment for creating the initial context + Hashtable env = new Hashtable(11); + env.put(Context.PROVIDER_URL, "ldap://localhost:22001"); + env.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.ldap.LdapCtxFactory"); + + // Wait up to 10 seconds for a response from the LDAP server + env.put("com.sun.jndi.ldap.read.timeout", "10000"); + + // Don't wait until the first search reply is received + env.put("com.sun.jndi.ldap.search.waitForReply", "false"); + + // Send the LDAP search request without first authenticating (no bind) + env.put("java.naming.ldap.version", "3"); + + DummyServer ldapServer = new DummyServer(); + + try { + + // start the LDAP server + ldapServer.start(); + + // Create initial context + System.out.println("Client: connecting to the server"); + DirContext ctx = new InitialDirContext(env); + + SearchControls scl = new SearchControls(); + scl.setSearchScope(SearchControls.SUBTREE_SCOPE); + System.out.println("Client: performing search"); + NamingEnumeration answer = + ctx.search("ou=People,o=JNDITutorial", "(objectClass=*)", scl); + + // Server will never reply: either we waited in the call above until + // the timeout (fail) or we did not wait and reached here (pass). + passed = true; + System.out.println("Client: did not wait until first reply"); + + // Close the context when we're done + ctx.close(); + + } catch (NamingException e) { + // timeout (ignore) + } + ldapServer.interrupt(); + + if (!passed) { + throw new Exception( + "Test FAILED: should not have waited until first search reply"); + } + System.out.println("Test PASSED"); + } + + static class DummyServer extends Thread { + + static int serverPort = 22001; + + DummyServer() { + } + + public void run() { + try { + ServerSocket serverSock = new ServerSocket(serverPort); + Socket socket = serverSock.accept(); + System.out.println("Server: accepted a connection"); + BufferedInputStream bin = + new BufferedInputStream(socket.getInputStream()); + + while (true) { + bin.read(); + } + } catch (IOException e) { + // ignore + } + } +} +} diff -r e2df5f8fa082 -r 7b224edc9990 jdk/test/java/lang/Thread/StartOOMTest.java --- a/jdk/test/java/lang/Thread/StartOOMTest.java Thu Mar 03 17:14:23 2011 +0000 +++ b/jdk/test/java/lang/Thread/StartOOMTest.java Thu Mar 03 17:16:13 2011 +0000 @@ -22,11 +22,14 @@ */ /* - * @test - * @bug 6379235 - * @ignore until 6721694 is fixed - * @run main/othervm -server -Xmx32m -Xms32m -Xss256m StartOOMTest - * @summary ThreadGroup accounting mistake possible with failure of Thread.start() + * This test is relatively useful for verifying 6379235, but + * is too resource intensive, especially on 64 bit systems, + * to be run automatically, see 6721694. + * + * When run it should be typically be run with the server vm + * and a relatively small java heap, and a large stack size + * ( to provoke the OOM quicker ). + * java -server -Xmx32m -Xms32m -Xss256m StartOOMTest */ import java.util.*;