summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-20 14:03:55 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-20 14:03:55 -0800
commit4351da844f9132d2d801d1a10ccc195091e31a8a (patch)
treebaeef62a8d92d647bdedb71625e7fadae385f867
parentd94c06c605baa7814b787bab7c993775b486ffba (diff)
downloadlibcore-4351da844f9132d2d801d1a10ccc195091e31a8a.zip
libcore-4351da844f9132d2d801d1a10ccc195091e31a8a.tar.gz
libcore-4351da844f9132d2d801d1a10ccc195091e31a8a.tar.bz2
auto import from //branches/cupcake/...@127101
-rw-r--r--annotation/src/main/java/java/lang/annotation/Retention.java13
-rw-r--r--luni/src/main/java/java/util/HashMap.java29
-rw-r--r--luni/src/main/java/java/util/LinkedHashMap.java35
-rwxr-xr-xluni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp48
-rw-r--r--x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java59
5 files changed, 130 insertions, 54 deletions
diff --git a/annotation/src/main/java/java/lang/annotation/Retention.java b/annotation/src/main/java/java/lang/annotation/Retention.java
index 1c440ae..198fccc 100644
--- a/annotation/src/main/java/java/lang/annotation/Retention.java
+++ b/annotation/src/main/java/java/lang/annotation/Retention.java
@@ -17,14 +17,10 @@
package java.lang.annotation;
-// BEGIN android-note
-// Un-linked RetentionPolicy#RUNTIME due to clearjavadoc problem (it doesn't
-// yet deal with links to enums).
-// END android-note
-
/**
* Defines a meta-annotation for determining the scope of retention for an
- * annotation. The default value is {@code RetentionPolicy.RUNTIME}.
+ * annotation. If the retention annotation is not set {@code
+ * RetentionPolicy.CLASS} is used as default retention.
*
* @since Android 1.0
*/
@@ -32,5 +28,8 @@ package java.lang.annotation;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
- RetentionPolicy value() default RetentionPolicy.CLASS;
+ // BEGIN android-changed
+ // copied from newer version of harmony
+ RetentionPolicy value();
+ // END android-changed
}
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 056c113..594e8a8 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -299,6 +299,7 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
putAllImpl(map);
}
+ // BEGIN android-changed
/**
* Removes all mappings from this hash map, leaving it empty.
*
@@ -308,12 +309,17 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
*/
@Override
public void clear() {
+ internalClear();
+ }
+
+ void internalClear() {
if (elementCount > 0) {
elementCount = 0;
Arrays.fill(elementData, null);
modCount++;
}
}
+ // END android-changed
/**
* Returns a shallow copy of this map.
@@ -326,9 +332,10 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
public Object clone() {
try {
// BEGIN android-changed
+ // copied from newer version of harmony
HashMap<K, V> map = (HashMap<K, V>) super.clone();
- map.elementCount = 0;
map.elementData = newElementArray(elementData.length);
+ map.internalClear();
Entry<K, V> entry;
for (int i = 0; i < elementData.length; i++) {
if ((entry = elementData[i]) != null){
@@ -448,20 +455,26 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
final Entry<K,V> findNonNullKeyEntry(Object key, int index, int keyHash) {
Entry<K,V> m = elementData[index];
// BEGIN android-changed
- while (m != null) {
- if (m.origKeyHash == keyHash) {
- if (key instanceof String) {
- // The VM can optimize String.equals but not Object.equals
- if (((String) key).equals(m.key)) {
+ // The VM can optimize String.equals but not Object.equals
+ if (key instanceof String) {
+ String keyString = (String) key;
+ while (m != null) {
+ if (m.origKeyHash == keyHash) {
+ if (keyString.equals(m.key)) {
return m;
}
- } else {
+ }
+ m = m.next;
+ }
+ } else {
+ while (m != null) {
+ if (m.origKeyHash == keyHash) {
if (key.equals(m.key)) {
return m;
}
}
+ m = m.next;
}
- m = m.next;
}
return null;
// END android-changed
diff --git a/luni/src/main/java/java/util/LinkedHashMap.java b/luni/src/main/java/java/util/LinkedHashMap.java
index 1a61345..a32a28b 100644
--- a/luni/src/main/java/java/util/LinkedHashMap.java
+++ b/luni/src/main/java/java/util/LinkedHashMap.java
@@ -19,9 +19,10 @@ package java.util;
/**
- * LinkedHashMap is a variant on HashMap. Its entries are kept in a
+ * LinkedHashMap is a variant of HashMap. Its entries are kept in a
* doubly-linked list. The iteration order is, by default, the order in which
- * keys were inserted.
+ * keys were inserted. Reinserting an already existing key doesn't change the
+ * order. A key is existing if a call to {@code containsKey} would return true.
* <p>
* If the three argument constructor is used, and {@code order} is specified as
* {@code true}, the iteration will be in the order that entries were accessed.
@@ -30,6 +31,21 @@ package java.util;
* <p>
* Null elements are allowed, and all the optional map operations are supported.
* <p>
+ * <b>Note:</b> The implementation of {@code LinkedHashMap} is not synchronized.
+ * If one thread of several threads accessing an instance modifies the map
+ * structurally, access to the map needs to be synchronized. For
+ * insertion-ordered instances a structural modification is an operation that
+ * removes or adds an entry. Access-ordered instances also are structurally
+ * modified by put(), get() and putAll() since these methods change the order of
+ * the entries. Changes in the value of an entry are not structural changes.
+ * <p>
+ * The Iterator that can be created by calling the {@code iterator} method
+ * throws a {@code ConcurrentModificationException} if the map is structurally
+ * changed while an iterator is used to iterate over the elements. Only the
+ * {@code remove} method that is provided by the iterator allows for removal of
+ * elements during iteration. It is not possible to guarantee that this
+ * mechanism works in all cases of unsynchronized concurrent modification. It
+ * should only be used for debugging purposes.
*
* @since Android 1.0
*/
@@ -115,7 +131,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
/**
* Constructs a new {@code LinkedHashMap} instance containing the mappings
- * from the specified map.
+ * from the specified map. The order of the elements is preserved.
*
* @param m
* the mappings to add.
@@ -314,6 +330,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
}
// BEGIN android-changed
+ // copied from newer version of harmony
/**
* Maps the specified key to the specified value.
*
@@ -352,7 +369,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
if (++elementCount > threshold) {
rehash();
}
- m = (LinkedHashMapEntry<K, V>) createHashedEntry(key, 0, 0);
+ m = (LinkedHashMapEntry<K, V>) createHashedEntry(null, 0, 0);
} else {
linkEntry(m);
}
@@ -595,6 +612,7 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
return false;
}
+ // BEGIN android-changed
/**
* Removes all elements from this map, leaving it empty.
*
@@ -604,11 +622,18 @@ public class LinkedHashMap<K, V> extends HashMap<K, V> {
*/
@Override
public void clear() {
- super.clear();
+ internalClear();
+ }
+
+ @Override
+ void internalClear() {
+ super.internalClear();
head = tail = null;
}
+ // END android-changed
// BEGIN android-removed
+ // copied from newer version of harmony
// /**
// * Answers a new HashMap with the same mappings and size as this HashMap.
// *
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index 7afb54e..de01295 100755
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -1469,18 +1469,48 @@ static jint osNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz,
return 0;
}
- while (sent < count) {
- result = send(handle, (jbyte *) message + sent, (int) count - sent, SOCKET_NOFLAGS);
- if (result == -1) {
- int err = convertError(errno);
- log_socket_close(handle, err);
- throwSocketException(env, err);
+ result = send(handle, (jbyte *) message, (int) count, SOCKET_NOFLAGS);
+ if (result < 0) {
+ int err = convertError(errno);
+ log_socket_close(handle, err);
+
+ if (SOCKERR_WOULDBLOCK == err){
+ jclass socketExClass,errorCodeExClass;
+ jmethodID errorCodeExConstructor, socketExConstructor,socketExCauseMethod;
+ jobject errorCodeEx, socketEx;
+ const char* errorMessage = netLookupErrorString(err);
+ jstring errorMessageString = env->NewStringUTF(errorMessage);
+
+ errorCodeExClass = env->FindClass("org/apache/harmony/luni/util/ErrorCodeException");
+ if (!errorCodeExClass){
+ return 0;
+ }
+ errorCodeExConstructor = env->GetMethodID(errorCodeExClass,"<init>","(I)V");
+ if (!errorCodeExConstructor){
+ return 0;
+ }
+ errorCodeEx = env->NewObject(errorCodeExClass,errorCodeExConstructor,err);
+
+ socketExClass = env->FindClass("java/net/SocketException");
+ if (!socketExClass) {
+ return 0;
+ }
+ socketExConstructor = env->GetMethodID(socketExClass,"<init>","(Ljava/lang/String;)V");
+ if (!socketExConstructor) {
+ return 0;
+ }
+ socketEx = env->NewObject(socketExClass, socketExConstructor, errorMessageString);
+ socketExCauseMethod = env->GetMethodID(socketExClass,"initCause","(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
+ env->CallObjectMethod(socketEx,socketExCauseMethod,errorCodeEx);
+ env->Throw((jthrowable)socketEx);
return 0;
}
- sent += result;
+ throwSocketException(env, err);
+ return 0;
}
- add_send_stats(handle, sent);
- return sent;
+
+ add_send_stats(handle, result);
+ return result;
}
static jint osNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz,
diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java
index 3c6a3b8..6882aa1 100644
--- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java
+++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLSessionContextImpl.java
@@ -36,6 +36,7 @@
*/
package org.apache.harmony.xnet.provider.jsse;
+import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -54,25 +55,28 @@ public class SSLSessionContextImpl implements SSLSessionContext {
private int cacheSize = 20;
private long timeout = 0;
- private final LinkedHashMap<byte[], SSLSession> sessions =
- new LinkedHashMap<byte[],SSLSession>(cacheSize, 0.75f, true) {
- public boolean removeEldestEntry(Map.Entry eldest) {
+ private final LinkedHashMap<ByteBuffer, SSLSession> sessions =
+ new LinkedHashMap<ByteBuffer, SSLSession>(cacheSize, 0.75f, true) {
+ @Override
+ public boolean removeEldestEntry(
+ Map.Entry<ByteBuffer, SSLSession> eldest) {
return cacheSize > 0 && this.size() > cacheSize;
}
};
- private volatile LinkedHashMap<byte[], SSLSession> clone = new LinkedHashMap<byte[], SSLSession>();
+ private volatile LinkedHashMap<ByteBuffer, SSLSession> clone =
+ new LinkedHashMap<ByteBuffer, SSLSession>();
/**
* @see javax.net.ssl.SSLSessionContext#getIds()
*/
public Enumeration<byte[]> getIds() {
return new Enumeration<byte[]>() {
- Iterator<byte[]> iterator = clone.keySet().iterator();
+ Iterator<ByteBuffer> iterator = clone.keySet().iterator();
public boolean hasMoreElements() {
return iterator.hasNext();
}
public byte[] nextElement() {
- return iterator.next();
+ return iterator.next().array();
}
};
}
@@ -82,7 +86,7 @@ public class SSLSessionContextImpl implements SSLSessionContext {
*/
public SSLSession getSession(byte[] sessionId) {
synchronized (sessions) {
- return (SSLSession) sessions.get(sessionId);
+ return sessions.get(ByteBuffer.wrap(sessionId));
}
}
@@ -90,14 +94,18 @@ public class SSLSessionContextImpl implements SSLSessionContext {
* @see javax.net.ssl.SSLSessionContext#getSessionCacheSize()
*/
public int getSessionCacheSize() {
- return cacheSize;
+ synchronized (sessions) {
+ return cacheSize;
+ }
}
/**
* @see javax.net.ssl.SSLSessionContext#getSessionTimeout()
*/
public int getSessionTimeout() {
- return (int) (timeout/1000);
+ synchronized (sessions) {
+ return (int) (timeout/1000);
+ }
}
/**
@@ -109,18 +117,16 @@ public class SSLSessionContextImpl implements SSLSessionContext {
}
synchronized (sessions) {
cacheSize = size;
- Set<byte[]> set = sessions.keySet();
- if (cacheSize > 0 && cacheSize < set.size()) {
- // Resize the cache to the maximum
- Iterator<byte[]> iterator = set.iterator();
- for (int i = 0; iterator.hasNext(); i++) {
+ if (cacheSize > 0 && cacheSize < sessions.size()) {
+ int removals = sessions.size() - cacheSize;
+ Iterator<ByteBuffer> iterator = sessions.keySet().iterator();
+ while (removals-- > 0) {
iterator.next();
- if (i >= cacheSize) {
- iterator.remove();
- }
+ iterator.remove();
}
+ clone = (LinkedHashMap<ByteBuffer, SSLSession>)
+ sessions.clone();
}
- clone = (LinkedHashMap<byte[], SSLSession>) sessions.clone();
}
}
@@ -131,18 +137,21 @@ public class SSLSessionContextImpl implements SSLSessionContext {
if (seconds < 0) {
throw new IllegalArgumentException("seconds < 0");
}
-
synchronized (sessions) {
timeout = seconds*1000;
// Check timeouts and remove expired sessions
SSLSession ses;
- for (Iterator<byte[]> iterator = sessions.keySet().iterator(); iterator.hasNext();) {
- ses = (SSLSession)(sessions.get(iterator.next()));
- if (!ses.isValid()) {
+ Iterator<Map.Entry<ByteBuffer, SSLSession>> iterator =
+ sessions.entrySet().iterator();
+ while (iterator.hasNext()) {
+ SSLSession session = iterator.next().getValue();
+ if (!session.isValid()) {
+ // safe to remove with this special method since it doesn't
+ // make the iterator throw a ConcurrentModificationException
iterator.remove();
}
}
- clone = (LinkedHashMap<byte[], SSLSession>) sessions.clone();
+ clone = (LinkedHashMap<ByteBuffer, SSLSession>) sessions.clone();
}
}
@@ -152,8 +161,8 @@ public class SSLSessionContextImpl implements SSLSessionContext {
*/
void putSession(SSLSession ses) {
synchronized (sessions) {
- sessions.put(ses.getId(), ses);
- clone = (LinkedHashMap<byte[], SSLSession>) sessions.clone();
+ sessions.put(ByteBuffer.wrap(ses.getId()), ses);
+ clone = (LinkedHashMap<ByteBuffer, SSLSession>) sessions.clone();
}
}
}