diff --git a/CHANGES.txt b/CHANGES.txt index 95e9a14e6a..d8957faf40 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -185,8 +185,8 @@ Trunk (unreleased changes) HADOOP-6599 Split existing RpcMetrics into RpcMetrics & RpcDetailedMetrics. (Suresh Srinivas via Sanjay Radia) - HADOOP-6537 Declare more detailed exceptions in FileContext and AbstractFileSystem - (Suresh Srinivas via Sanjay Radia) + HADOOP-6537 Declare more detailed exceptions in FileContext and + AbstractFileSystem (Suresh Srinivas via Sanjay Radia) OPTIMIZATIONS @@ -264,6 +264,9 @@ Trunk (unreleased changes) HADOOP-6545. Changes the Key for the FileSystem cache to be UGI (ddas) + HADOOP-6609. Fixed deadlock in RPC by replacing shared static + DataOutputBuffer in the UTF8 class with a thread local variable. (omalley) + Release 0.21.0 - Unreleased INCOMPATIBLE CHANGES diff --git a/src/java/org/apache/hadoop/io/UTF8.java b/src/java/org/apache/hadoop/io/UTF8.java index 4b3e2379b7..20b00b769c 100644 --- a/src/java/org/apache/hadoop/io/UTF8.java +++ b/src/java/org/apache/hadoop/io/UTF8.java @@ -33,9 +33,16 @@ */ public class UTF8 implements WritableComparable { private static final Log LOG= LogFactory.getLog(UTF8.class); - private static final DataOutputBuffer OBUF = new DataOutputBuffer(); private static final DataInputBuffer IBUF = new DataInputBuffer(); + private static final ThreadLocal OBUF_FACTORY = + new ThreadLocal(){ + @Override + protected DataOutputBuffer initialValue() { + return new DataOutputBuffer(); + } + }; + private static final byte[] EMPTY_BYTES = new byte[0]; private byte[] bytes = EMPTY_BYTES; @@ -81,11 +88,10 @@ public void set(String string) { bytes = new byte[length]; try { // avoid sync'd allocations - synchronized (OBUF) { - OBUF.reset(); - writeChars(OBUF, string, 0, string.length()); - System.arraycopy(OBUF.getData(), 0, bytes, 0, length); - } + DataOutputBuffer obuf = OBUF_FACTORY.get(); + obuf.reset(); + writeChars(obuf, string, 0, string.length()); + System.arraycopy(obuf.getData(), 0, bytes, 0, length); } catch (IOException e) { throw new RuntimeException(e); } @@ -182,11 +188,10 @@ public int compare(byte[] b1, int s1, int l1, public static byte[] getBytes(String string) { byte[] result = new byte[utf8Length(string)]; try { // avoid sync'd allocations - synchronized (OBUF) { - OBUF.reset(); - writeChars(OBUF, string, 0, string.length()); - System.arraycopy(OBUF.getData(), 0, result, 0, OBUF.getLength()); - } + DataOutputBuffer obuf = OBUF_FACTORY.get(); + obuf.reset(); + writeChars(obuf, string, 0, string.length()); + System.arraycopy(obuf.getData(), 0, result, 0, obuf.getLength()); } catch (IOException e) { throw new RuntimeException(e); } @@ -206,23 +211,22 @@ public static String readString(DataInput in) throws IOException { private static void readChars(DataInput in, StringBuffer buffer, int nBytes) throws IOException { - synchronized (OBUF) { - OBUF.reset(); - OBUF.write(in, nBytes); - byte[] bytes = OBUF.getData(); - int i = 0; - while (i < nBytes) { - byte b = bytes[i++]; - if ((b & 0x80) == 0) { - buffer.append((char)(b & 0x7F)); - } else if ((b & 0xE0) != 0xE0) { - buffer.append((char)(((b & 0x1F) << 6) - | (bytes[i++] & 0x3F))); - } else { - buffer.append((char)(((b & 0x0F) << 12) - | ((bytes[i++] & 0x3F) << 6) - | (bytes[i++] & 0x3F))); - } + DataOutputBuffer obuf = OBUF_FACTORY.get(); + obuf.reset(); + obuf.write(in, nBytes); + byte[] bytes = obuf.getData(); + int i = 0; + while (i < nBytes) { + byte b = bytes[i++]; + if ((b & 0x80) == 0) { + buffer.append((char)(b & 0x7F)); + } else if ((b & 0xE0) != 0xE0) { + buffer.append((char)(((b & 0x1F) << 6) + | (bytes[i++] & 0x3F))); + } else { + buffer.append((char)(((b & 0x0F) << 12) + | ((bytes[i++] & 0x3F) << 6) + | (bytes[i++] & 0x3F))); } } }