diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-20 14:03:55 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-20 14:03:55 -0800 |
commit | 4351da844f9132d2d801d1a10ccc195091e31a8a (patch) | |
tree | baeef62a8d92d647bdedb71625e7fadae385f867 | |
parent | d94c06c605baa7814b787bab7c993775b486ffba (diff) | |
download | libcore-4351da844f9132d2d801d1a10ccc195091e31a8a.zip libcore-4351da844f9132d2d801d1a10ccc195091e31a8a.tar.gz libcore-4351da844f9132d2d801d1a10ccc195091e31a8a.tar.bz2 |
auto import from //branches/cupcake/...@127101
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(); } } } |