From a4bc0fa013264751df2976aa023b5f1a39d2fd82 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 12 Jun 2012 13:54:20 -0700 Subject: [PATCH 1/6] 7176138: Fixes for missing close() calls and possible null pointer reference instead of fatal error Reviewed-by: dcubed --- jdk/src/share/demo/jvmti/hprof/hprof_table.c | 11 ++++++----- jdk/src/solaris/demo/jvmti/hprof/hprof_md.c | 5 +++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_table.c b/jdk/src/share/demo/jvmti/hprof/hprof_table.c index 19b0c425398..c2c205eb939 100644 --- a/jdk/src/share/demo/jvmti/hprof/hprof_table.c +++ b/jdk/src/share/demo/jvmti/hprof/hprof_table.c @@ -120,7 +120,7 @@ typedef struct LookupTable { TableIndex table_incr; /* Suggested increment size. */ TableIndex hash_bucket_count; /* Number of hash buckets. */ int elem_size; /* Size of element. */ - int info_size; /* Size of info structure. */ + int info_size; /* Size of info structure (can be 0). */ void *freed_bv; /* Freed element bit vector */ int freed_count; /* Count of freed'd elements */ TableIndex freed_start; /* First freed in table */ @@ -208,9 +208,6 @@ get_info(LookupTable *ltable, TableIndex index) { TableElement *element; - if ( ltable->info_size == 0 ) { - return NULL; - } element = (TableElement*)ELEMENT_PTR(ltable,index); return element->info; } @@ -760,7 +757,11 @@ table_walk_items(LookupTable *ltable, LookupTableIterator func, void* arg) void *info; get_key(ltable, index, &key_ptr, &key_len); - info = get_info(ltable, index); + if ( ltable->info_size == 0 ) { + info = NULL; + } else { + info = get_info(ltable, index); + } (*func)(SANITY_ADD_HARE(index, ltable->hare), key_ptr, key_len, info, arg); if ( is_freed_entry(ltable, index) ) { fcount++; diff --git a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c index 1e93bd656a6..63469a56626 100644 --- a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c +++ b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c @@ -119,9 +119,13 @@ md_connect(char *hostname, unsigned short port) /* create a socket */ fd = socket(AF_INET, SOCK_STREAM, 0); + if ( fd < 0 ) { + return -1; + } /* find remote host's addr from name */ if ((hentry = gethostbyname(hostname)) == NULL) { + (void)close(fd); return -1; } (void)memset((char *)&s, 0, sizeof(s)); @@ -134,6 +138,7 @@ md_connect(char *hostname, unsigned short port) /* now try connecting */ if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) { + (void)close(fd); return 0; } return fd; From 0b0b610a21359acd30b3c076a9e23eb89d09a63e Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Tue, 12 Jun 2012 17:32:01 -0400 Subject: [PATCH 2/6] 7171918: XmlReaderContentHandler.endElement does not handle a Delete Tag properly Reviewed-by: joehw --- .../classes/com/sun/rowset/internal/XmlReaderContentHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java index 2d36ac174d8..eb159c6598a 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java @@ -764,6 +764,7 @@ public class XmlReaderContentHandler extends DefaultHandler { rs.next(); rs.setOriginalRow(); applyUpdates(); + rs.deleteRow(); } catch (SQLException ex) { throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage())); } From 911aeb6828de9c2bf44696505fe2f6a000fb0100 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 13 Jun 2012 19:23:23 +0800 Subject: [PATCH 3/6] 7176574: sun/security/krb5/auto/TcpTimeout.java failed with solaris-i586 Reviewed-by: chegar --- .../sun/security/krb5/auto/TcpTimeout.java | 81 +++++++++++-------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/jdk/test/sun/security/krb5/auto/TcpTimeout.java b/jdk/test/sun/security/krb5/auto/TcpTimeout.java index 6f55391a576..01bd58cfa70 100644 --- a/jdk/test/sun/security/krb5/auto/TcpTimeout.java +++ b/jdk/test/sun/security/krb5/auto/TcpTimeout.java @@ -48,49 +48,60 @@ public class TcpTimeout { k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM); // Start two listener that does not communicate, simulate timeout - int p1 = new ServerSocket(0).getLocalPort(); - int p2 = new ServerSocket(0).getLocalPort(); + ServerSocket ss1 = null; + ServerSocket ss2 = null; - FileWriter fw = new FileWriter("alternative-krb5.conf"); + try { + ss1 = new ServerSocket(0); + ss2 = new ServerSocket(0); + int p1 = ss1.getLocalPort(); + int p2 = ss2.getLocalPort(); - fw.write("[libdefaults]\n" + - "udp_preference_limit = 1\n" + - "max_retries = 2\n" + - "default_realm = " + OneKDC.REALM + "\n" + - "kdc_timeout = 5000\n"); - fw.write("[realms]\n" + OneKDC.REALM + " = {\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" + - "}\n"); + FileWriter fw = new FileWriter("alternative-krb5.conf"); - fw.close(); - System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); - Config.refresh(); + fw.write("[libdefaults]\n" + + "udp_preference_limit = 1\n" + + "max_retries = 2\n" + + "default_realm = " + OneKDC.REALM + "\n" + + "kdc_timeout = 5000\n"); + fw.write("[realms]\n" + OneKDC.REALM + " = {\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" + + "}\n"); - System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3); + fw.close(); + System.setProperty("java.security.krb5.conf", + "alternative-krb5.conf"); + Config.refresh(); - // The correct behavior should be: - // 5 sec on p1, 5 sec on p1, fail - // 5 sec on p2, 5 sec on p2, fail - // p3 ok, p3 ok again for preauth. - int count = 6; + System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3); - ByteArrayOutputStream bo = new ByteArrayOutputStream(); - PrintStream oldout = System.out; - System.setOut(new PrintStream(bo)); - Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); - System.setOut(oldout); + // The correct behavior should be: + // 5 sec on p1, 5 sec on p1, fail + // 5 sec on p2, 5 sec on p2, fail + // p3 ok, p3 ok again for preauth. + int count = 6; - String[] lines = new String(bo.toByteArray()).split("\n"); - for (String line: lines) { - if (line.startsWith(">>> KDCCommunication")) { - System.out.println(line); - count--; + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + PrintStream oldout = System.out; + System.setOut(new PrintStream(bo)); + Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + System.setOut(oldout); + + String[] lines = new String(bo.toByteArray()).split("\n"); + for (String line: lines) { + if (line.startsWith(">>> KDCCommunication")) { + System.out.println(line); + count--; + } } - } - if (count != 0) { - throw new Exception("Retry count is " + count + " less"); + if (count != 0) { + throw new Exception("Retry count is " + count + " less"); + } + } finally { + if (ss1 != null) ss1.close(); + if (ss2 != null) ss2.close(); } } } From c580cfee8015174eca0a2424178c180c3d3c5e0c Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Thu, 14 Jun 2012 12:13:54 +0100 Subject: [PATCH 4/6] 7176630: (sc) SocketChannel.write does not write more than 128k when channel configured blocking [win] Reviewed-by: khazra, chegar --- .../native/sun/nio/ch/SocketDispatcher.c | 59 +++++--- .../channels/SocketChannel/ShortWrite.java | 136 ++++++++++++++++++ 2 files changed, 172 insertions(+), 23 deletions(-) create mode 100644 jdk/test/java/nio/channels/SocketChannel/ShortWrite.java diff --git a/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c b/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c index 4dc8259dfc4..373d92da7a7 100644 --- a/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c +++ b/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c @@ -141,41 +141,54 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo, JNIEXPORT jint JNICALL Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo, - jlong address, jint len) + jlong address, jint total) { /* set up */ int i = 0; DWORD written = 0; + jint count = 0; jint fd = fdval(env, fdo); WSABUF buf; - /* limit size */ - if (len > MAX_BUFFER_SIZE) - len = MAX_BUFFER_SIZE; + do { + /* limit size */ + jint len = total - count; + if (len > MAX_BUFFER_SIZE) + len = MAX_BUFFER_SIZE; - /* copy iovec into WSABUF */ - buf.buf = (char *)address; - buf.len = (u_long)len; + /* copy iovec into WSABUF */ + buf.buf = (char *)address; + buf.len = (u_long)len; - /* read into the buffers */ - i = WSASend((SOCKET)fd, /* Socket */ - &buf, /* pointers to the buffers */ - (DWORD)1, /* number of buffers to process */ - &written, /* receives number of bytes written */ - 0, /* no flags */ - 0, /* no overlapped sockets */ - 0); /* no completion routine */ + /* write from the buffer */ + i = WSASend((SOCKET)fd, /* Socket */ + &buf, /* pointers to the buffers */ + (DWORD)1, /* number of buffers to process */ + &written, /* receives number of bytes written */ + 0, /* no flags */ + 0, /* no overlapped sockets */ + 0); /* no completion routine */ - if (i == SOCKET_ERROR) { - int theErr = (jint)WSAGetLastError(); - if (theErr == WSAEWOULDBLOCK) { - return IOS_UNAVAILABLE; + if (i == SOCKET_ERROR) { + if (count > 0) { + /* can't throw exception when some bytes have been written */ + break; + } else { + int theErr = (jint)WSAGetLastError(); + if (theErr == WSAEWOULDBLOCK) { + return IOS_UNAVAILABLE; + } + JNU_ThrowIOExceptionWithLastError(env, "Write failed"); + return IOS_THROWN; + } } - JNU_ThrowIOExceptionWithLastError(env, "Write failed"); - return IOS_THROWN; - } - return convertReturnVal(env, (jint)written, JNI_FALSE); + count += written; + address += written; + + } while ((count < total) && (written == MAX_BUFFER_SIZE)); + + return count; } JNIEXPORT jlong JNICALL diff --git a/jdk/test/java/nio/channels/SocketChannel/ShortWrite.java b/jdk/test/java/nio/channels/SocketChannel/ShortWrite.java new file mode 100644 index 00000000000..2f324c33c1b --- /dev/null +++ b/jdk/test/java/nio/channels/SocketChannel/ShortWrite.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012, 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 7176630 + * @summary Check for short writes on SocketChannels configured in blocking mode + */ + +import java.net.*; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.concurrent.*; +import java.util.Random; +import java.util.zip.CRC32; + +public class ShortWrite { + + static final Random rand = new Random(); + + /** + * Returns a checksum on the remaining bytes in the given buffer. + */ + static long computeChecksum(ByteBuffer bb) { + CRC32 crc32 = new CRC32(); + crc32.update(bb); + return crc32.getValue(); + } + + /** + * A task that reads the expected number of bytes and returns the CRC32 + * of those bytes. + */ + static class Reader implements Callable { + final SocketChannel sc; + final ByteBuffer buf; + + Reader(SocketChannel sc, int expectedSize) { + this.sc = sc; + this.buf = ByteBuffer.allocate(expectedSize); + } + + public Long call() throws Exception { + while (buf.hasRemaining()) { + int n = sc.read(buf); + if (n == -1) + throw new RuntimeException("Premature EOF encountered"); + } + buf.flip(); + return computeChecksum(buf); + } + } + + /** + * Run test with a write of the given number of bytes. + */ + static void test(ExecutorService pool, + SocketChannel source, + SocketChannel sink, + int size) + throws Exception + { + System.out.println(size); + + // random bytes in the buffer + ByteBuffer buf = ByteBuffer.allocate(size); + rand.nextBytes(buf.array()); + + // submit task to read the bytes + Future result = pool.submit(new Reader(sink, size)); + + // write the bytes + int n = source.write(buf); + if (n != size) + throw new RuntimeException("Short write detected"); + + // check the bytes that were received match + buf.rewind(); + long expected = computeChecksum(buf); + long actual = result.get(); + if (actual != expected) + throw new RuntimeException("Checksum did not match"); + } + + + public static void main(String[] args) throws Exception { + ExecutorService pool = Executors.newSingleThreadExecutor(); + try { + try (ServerSocketChannel ssc = ServerSocketChannel.open()) { + ssc.bind(new InetSocketAddress(0)); + InetAddress lh = InetAddress.getLocalHost(); + int port = ssc.socket().getLocalPort(); + SocketAddress sa = new InetSocketAddress(lh, port); + + try (SocketChannel source = SocketChannel.open(sa); + SocketChannel sink = ssc.accept()) + { + // run tests on sizes around 128k as that is the problem + // area on Windows. + int BOUNDARY = 128 * 1024; + for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) { + test(pool, source, sink, size); + } + + // run tests on random sizes + for (int i=0; i<20; i++) { + int size = rand.nextInt(1024*1024); + test(pool, source, sink, size); + } + } + } + + } finally { + pool.shutdown(); + } + } +} From 4824bf600d5033f6041d6d98c359d5c22961e2cc Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Wed, 13 Jun 2012 16:48:30 -0700 Subject: [PATCH 5/6] 7173919: Minor optimization of hashing methods Several minor optimizations to hashing methods used by hash map classes Reviewed-by: dholmes --- jdk/src/share/classes/java/util/HashMap.java | 5 ++--- .../share/classes/java/util/Hashtable.java | 20 +++++++++---------- .../share/classes/java/util/WeakHashMap.java | 6 ++---- .../util/concurrent/ConcurrentHashMap.java | 4 +--- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/jdk/src/share/classes/java/util/HashMap.java b/jdk/src/share/classes/java/util/HashMap.java index 2191b981344..4687905e428 100644 --- a/jdk/src/share/classes/java/util/HashMap.java +++ b/jdk/src/share/classes/java/util/HashMap.java @@ -288,12 +288,11 @@ public class HashMap * in lower bits. */ final int hash(Object k) { - int h = hashSeed; if (k instanceof String) { - return ((String)k).hash32(); + return ((String) k).hash32(); } - h ^= k.hashCode(); + int h = hashSeed ^ k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index 593c1710a2a..f82c300838e 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -194,19 +194,17 @@ public class Hashtable transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this); private int hash(Object k) { - int h = hashSeed; - if (k instanceof String) { return ((String)k).hash32(); - } else { - h ^= k.hashCode(); - - // This function ensures that hashCodes that differ only by - // constant multiples at each bit position have a bounded - // number of collisions (approximately 8 at default load factor). - h ^= (h >>> 20) ^ (h >>> 12); - return h ^ (h >>> 7) ^ (h >>> 4); } + + int h = hashSeed ^ k.hashCode(); + + // This function ensures that hashCodes that differ only by + // constant multiples at each bit position have a bounded + // number of collisions (approximately 8 at default load factor). + h ^= (h >>> 20) ^ (h >>> 12); + return h ^ (h >>> 7) ^ (h >>> 4); } /** @@ -1015,7 +1013,7 @@ public class Hashtable */ private static class Entry implements Map.Entry { final int hash; - K key; + final K key; V value; Entry next; diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java index ed9e1ad9396..26e22aa10d3 100644 --- a/jdk/src/share/classes/java/util/WeakHashMap.java +++ b/jdk/src/share/classes/java/util/WeakHashMap.java @@ -295,13 +295,11 @@ public class WeakHashMap * otherwise encounter collisions for hashCodes that do not differ * in lower bits. */ - int hash(Object k) { - int h = hashSeed; + final int hash(Object k) { if (k instanceof String) { return ((String) k).hash32(); - } else { - h ^= k.hashCode(); } + int h = hashSeed ^ k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java index deddc7f0496..66ae51667d5 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -269,13 +269,11 @@ public class ConcurrentHashMap extends AbstractMap * differ in lower or upper bits. */ private int hash(Object k) { - int h = hashSeed; - if (k instanceof String) { return ((String) k).hash32(); } - h ^= k.hashCode(); + int h = hashSeed ^ k.hashCode(); // Spread bits to regularize both segment and index locations, // using variant of single-word Wang/Jenkins hash. From 4bb6dcf36b39db39a4c265f74fd97d3b31bf0d34 Mon Sep 17 00:00:00 2001 From: Lance Andersen Date: Thu, 14 Jun 2012 15:05:18 -0400 Subject: [PATCH 6/6] 7145913: CachedRowSetSwriter.insertNewRow() throws SQLException Reviewed-by: joehw, naoto, psandoz, forax --- .../rowset/internal/CachedRowSetWriter.java | 215 +++++++++++------- 1 file changed, 127 insertions(+), 88 deletions(-) diff --git a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java index 4737fb329bf..8824f8c0f0a 100644 --- a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java +++ b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, 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 @@ -812,101 +812,119 @@ public class CachedRowSetWriter implements TransactionalWriter, Serializable { } } - /** - * Inserts a row that has been inserted into the given - * CachedRowSet object into the data source from which - * the rowset is derived, returning false if the insertion - * was successful. - * - * @param crs the CachedRowSet object that has had a row inserted - * and to whose underlying data source the row will be inserted - * @param pstmt the PreparedStatement object that will be used - * to execute the insertion - * @return false to indicate that the insertion was successful; - * true otherwise - * @throws SQLException if a database access error occurs - */ - private boolean insertNewRow(CachedRowSet crs, - PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException { - int i = 0; - int icolCount = crs.getMetaData().getColumnCount(); + /** + * Inserts a row that has been inserted into the given + * CachedRowSet object into the data source from which + * the rowset is derived, returning false if the insertion + * was successful. + * + * @param crs the CachedRowSet object that has had a row inserted + * and to whose underlying data source the row will be inserted + * @param pstmt the PreparedStatement object that will be used + * to execute the insertion + * @return false to indicate that the insertion was successful; + * true otherwise + * @throws SQLException if a database access error occurs + */ + private boolean insertNewRow(CachedRowSet crs, + PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException { - boolean returnVal = false; - PreparedStatement pstmtSel = con.prepareStatement(selectCmd, - ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); - ResultSet rs, rs2 = null; - DatabaseMetaData dbmd = con.getMetaData(); - rs = pstmtSel.executeQuery(); - String table = crs.getTableName(); - rs2 = dbmd.getPrimaryKeys(null, null, table); - String [] primaryKeys = new String[icolCount]; - int k = 0; - while(rs2.next()) { - String pkcolname = rs2.getString("COLUMN_NAME"); - primaryKeys[k] = pkcolname; - k++; - } + boolean returnVal = false; - if(rs.next()) { - for(int j=0;j