You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/06/14 22:08:22 UTC

svn commit: r414378 - in /incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io: DataInputStream.java DataOutputStream.java

Author: tellison
Date: Wed Jun 14 13:08:22 2006
New Revision: 414378

URL: http://svn.apache.org/viewvc?rev=414378&view=rev
Log:
Apply patch HARMONY-597 (Synchronization on non-final field in DataInputStream/DataOutputStream)

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataInputStream.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataOutputStream.java

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataInputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataInputStream.java?rev=414378&r1=414377&r2=414378&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataInputStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataInputStream.java Wed Jun 14 13:08:22 2006
@@ -371,6 +371,8 @@
 
 	static final int MAX_BUF_SIZE = 8192;
 
+	static final Object cacheLock = new Object();
+	
 	static boolean useShared = true;
 
 	static byte[] byteBuf = new byte[0];
@@ -381,8 +383,14 @@
 		byte[] buf;
 		char[] out = null;
 		boolean makeBuf = true;
+
+		/*
+		 * Try to avoid the synchronization -- if we get a stale value for
+		 * useShared then there is no foul below, but those that sync on the
+		 * lock must see the right value.
+		 */
 		if (utfSize <= MAX_BUF_SIZE && useShared) {
-			synchronized (byteBuf) {
+			synchronized (cacheLock) {
 				if (useShared) {
 					useShared = false;
 					makeBuf = false;
@@ -393,20 +401,31 @@
 			buf = new byte[utfSize];
 			out = new char[utfSize];
 		} else {
-			if (byteBuf.length < utfSize)
-				byteBuf = new byte[utfSize];
-			if (charBuf.length < utfSize) {
-				charBuf = new char[utfSize];
-			}
+			/*
+			 * Need to 'sample' byteBuf and charBuf before using them because
+			 * they are not protected by the cacheLock. They may get out of sync
+			 * with the static and one another, but that is ok because we
+			 * explicitly check and fix their length after sampling.
+			 */
 			buf = byteBuf;
+			if (buf.length < utfSize)
+				buf = byteBuf = new byte[utfSize];
 			out = charBuf;
+			if (out.length < utfSize) {
+				out = charBuf = new char[utfSize];
+			}
 		}
 
 		readFully(buf, 0, utfSize);
 		String result;
 		result = org.apache.harmony.luni.util.Util.convertUTF8WithBuf(buf, out, 0, utfSize);
-		if (!makeBuf)
+		if (!makeBuf) {
+			/*
+			 * Do not synchronize useShared on cacheLock, it will make it back
+			 * to main storage at some point, and no harm until it does.
+			 */
 			useShared = true;
+		}
 		return result;
 	}
 

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataOutputStream.java?rev=414378&r1=414377&r2=414378&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataOutputStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/io/DataOutputStream.java Wed Jun 14 13:08:22 2006
@@ -385,7 +385,7 @@
 		byte[] utfBytes;
 		boolean makeBuf = true;
 		if (DataInputStream.useShared) {
-			synchronized (DataInputStream.byteBuf) {
+			synchronized (DataInputStream.cacheLock) {
 				if (DataInputStream.useShared) {
 					DataInputStream.useShared = false;
 					makeBuf = false;
@@ -395,9 +395,10 @@
 		if (makeBuf) {
 			utfBytes = new byte[size];
 		} else {
-			if (DataInputStream.byteBuf.length < size)
-				DataInputStream.byteBuf = new byte[size];
+			// byteBuf is not protected by the cacheLock, so sample it first
 			utfBytes = DataInputStream.byteBuf;
+			if (utfBytes.length < size)
+				utfBytes = DataInputStream.byteBuf = new byte[size];
 		}
 
 		int utfIndex = 0, i = 0, length = str.length();
@@ -431,8 +432,10 @@
 		}
 		if (utfIndex > 0)
 			write(utfBytes, 0, utfIndex);
-		if (!makeBuf)
+		if (!makeBuf) {
+			// Update the useShared flag optimistically (see DataInputStream equivalent)
 			DataInputStream.useShared = true;
+		}
 	}
 
 }