[kaffe] CVS kaffe (robilad): Resynced with GNU Classpath: threading fixes

Kaffe CVS cvs-commits at kaffe.org
Tue Mar 8 13:54:12 PST 2005


PatchSet 5502 
Date: 2005/03/08 21:48:32
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
Resynced with GNU Classpath: threading fixes

2005-03-08  Dalibor Topic  <robilad at kaffe.org>

        Resynced with GNU Classpath.

        2005-03-03  Jeroen Frijters  <jeroen at frijters.net>

        * java/lang/InheritableThreadLocal.java
        (threadMap): Removed.
        (InheritableThreadLocal): Removed code.
        (newChildThread): Changed to use locals map in Thread.
        * java/lang/Thread.java
        (locals): New field.
        (die): Clear locals field.
        (getThreadLocals): New method.
        * java/lang/ThreadLocal.java
        (value): Removed.
        (valueMap): Removed.
        (get,set): Changed to use locals map in Thread.

Members: 
	ChangeLog:1.3676->1.3677 
	libraries/javalib/java/lang/InheritableThreadLocal.java:1.4->1.5 
	libraries/javalib/java/lang/Thread.java:1.54->1.55 
	libraries/javalib/java/lang/ThreadLocal.java:1.4->1.5 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3676 kaffe/ChangeLog:1.3677
--- kaffe/ChangeLog:1.3676	Tue Mar  8 21:05:55 2005
+++ kaffe/ChangeLog	Tue Mar  8 21:48:32 2005
@@ -2,6 +2,25 @@
 
 	Resynced with GNU Classpath.
 
+	2005-03-03  Jeroen Frijters  <jeroen at frijters.net>
+
+        * java/lang/InheritableThreadLocal.java
+        (threadMap): Removed.
+        (InheritableThreadLocal): Removed code.
+        (newChildThread): Changed to use locals map in Thread.
+        * java/lang/Thread.java
+        (locals): New field.
+        (die): Clear locals field.
+        (getThreadLocals): New method.
+        * java/lang/ThreadLocal.java
+        (value): Removed.
+        (valueMap): Removed.
+        (get,set): Changed to use locals map in Thread.
+
+2005-03-08  Dalibor Topic  <robilad at kaffe.org>
+
+	Resynced with GNU Classpath.
+
 	2005-03-02  Michael Koch  <konqueror at gmx.de>
 
         * gnu/java/security/OID.java,
Index: kaffe/libraries/javalib/java/lang/InheritableThreadLocal.java
diff -u kaffe/libraries/javalib/java/lang/InheritableThreadLocal.java:1.4 kaffe/libraries/javalib/java/lang/InheritableThreadLocal.java:1.5
--- kaffe/libraries/javalib/java/lang/InheritableThreadLocal.java:1.4	Sat Feb 19 15:04:16 2005
+++ kaffe/libraries/javalib/java/lang/InheritableThreadLocal.java	Tue Mar  8 21:48:35 2005
@@ -37,11 +37,7 @@
 
 package java.lang;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 import java.util.WeakHashMap;
 
 /**
@@ -64,30 +60,11 @@
 public class InheritableThreadLocal extends ThreadLocal
 {
   /**
-   * Maps Threads to a List of InheritableThreadLocals (the heritage of that
-   * Thread). Uses a WeakHashMap so if the Thread is garbage collected the
-   * List can be collected, too. Maps to a list in case the user overrides
-   * equals.
-   */
-  private static final Map threadMap
-	  = Collections.synchronizedMap(new WeakHashMap());
-
-  /**
    * Creates a new InheritableThreadLocal that has no values associated
    * with it yet.
    */
   public InheritableThreadLocal()
   {
-    Thread currentThread = Thread.currentThread();
-    // Note that we don't have to synchronize, as only this thread will
-    // ever modify the returned heritage and threadMap is a synchronizedMap.
-    List heritage = (List) threadMap.get(currentThread);
-    if (heritage == null)
-      {
-        heritage = new ArrayList();
-        threadMap.put(currentThread, heritage);
-      }
-    heritage.add(this);
   }
 
   /**
@@ -116,25 +93,22 @@
   {
     // The currentThread is the parent of the new thread.
     Thread parentThread = Thread.currentThread();
-    // Note that we don't have to synchronize, as only this thread will
-    // ever modify the returned heritage and threadMap is a synchronizedMap. 
-    ArrayList heritage = (ArrayList) threadMap.get(parentThread);
-    if (heritage != null)
+    if (parentThread.locals != null)
       {
-        threadMap.put(childThread, heritage.clone());
-        // Perform the inheritance.
-        Iterator it = heritage.iterator();
-        int i = heritage.size();
-        while (--i >= 0)
+        Iterator keys = parentThread.locals.keySet().iterator();
+        while (keys.hasNext())
           {
-            InheritableThreadLocal local = (InheritableThreadLocal) it.next();
-            Object parentValue = local.valueMap.get(parentThread);
-            if (parentValue != null)
+            Key key = (Key)keys.next();
+            if (key.get() instanceof InheritableThreadLocal)
               {
+                InheritableThreadLocal local = (InheritableThreadLocal)key.get();
+                Object parentValue = parentThread.locals.get(key);
                 Object childValue = local.childValue(parentValue == NULL
                                                      ? null : parentValue);
-                local.valueMap.put(childThread, (childValue == null
-                                                 ? NULL : childValue));
+                if (childThread.locals == null)
+                    childThread.locals = new WeakHashMap();
+                childThread.locals.put(key, (childValue == null
+                                             ? NULL : childValue));
               }
           }
       }
Index: kaffe/libraries/javalib/java/lang/Thread.java
diff -u kaffe/libraries/javalib/java/lang/Thread.java:1.54 kaffe/libraries/javalib/java/lang/Thread.java:1.55
--- kaffe/libraries/javalib/java/lang/Thread.java:1.54	Thu Feb 10 22:46:46 2005
+++ kaffe/libraries/javalib/java/lang/Thread.java	Tue Mar  8 21:48:35 2005
@@ -38,6 +38,8 @@
 
 package java.lang;
 
+import java.util.Map;
+import java.util.WeakHashMap;
 
 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
  * "The Java Language Specification", ISBN 0-201-63451-1
@@ -131,6 +133,11 @@
   /** The next thread number to use. */
   private static int numAnonymousThreadsCreated;
 
+  /** Thread local storage. Package accessible for use by
+    * InheritableThreadLocal.
+    */
+  WeakHashMap locals;
+
   /**
    * Allocates a new <code>Thread</code> object. This constructor has
    * the same effect as <code>Thread(null, null,</code>
@@ -976,5 +983,20 @@
   {
     group.removeThread(this);
     vmThread = null;
+    locals = null;
+  }
+
+  /**
+   * Returns the map used by ThreadLocal to store the thread local values.
+   */
+  static Map getThreadLocals()
+  {
+    Thread thread = currentThread();
+    Map locals = thread.locals;
+    if (locals == null)
+      {
+        locals = thread.locals = new WeakHashMap();
+      }
+    return locals;
   }
 }
Index: kaffe/libraries/javalib/java/lang/ThreadLocal.java
diff -u kaffe/libraries/javalib/java/lang/ThreadLocal.java:1.4 kaffe/libraries/javalib/java/lang/ThreadLocal.java:1.5
--- kaffe/libraries/javalib/java/lang/ThreadLocal.java:1.4	Fri Oct 15 14:25:01 2004
+++ kaffe/libraries/javalib/java/lang/ThreadLocal.java	Tue Mar  8 21:48:35 2005
@@ -37,7 +37,6 @@
 
 package java.lang;
 
-import java.util.Collections;
 import java.util.Map;
 import java.util.WeakHashMap;
 
@@ -98,18 +97,20 @@
   static final Object NULL = new Object();
 
   /**
-   * The stored value. Package visible for use by InheritableThreadLocal. */
-  Object value;
-	
-  /**
-   * Maps Threads to values. Uses a WeakHashMap so if a Thread is garbage
-   * collected the reference to the Value will disappear. A null value means
-   * uninitialized, while NULL means a user-specified null. Only the
-   * <code>set(Thread, Object)</code> and <code>get(Thread)</code> methods
-   * access it. Package visible for use by InheritableThreadLocal.
+   * Serves as a key for the Thread.locals WeakHashMap.
+   * We can't use "this", because a subclass may override equals/hashCode
+   * and we need to use object identity for the map.
    */
-  final Map valueMap = Collections.synchronizedMap(new WeakHashMap());
-	
+  final Key key = new Key();
+
+  class Key
+  {
+    ThreadLocal get()
+    {
+      return ThreadLocal.this;
+    }
+  }
+
   /**
    * Creates a ThreadLocal object without associating any value to it yet.
    */
@@ -140,14 +141,14 @@
    */
   public Object get()
   {
-    Thread currentThread = Thread.currentThread();
+    Map map = Thread.getThreadLocals();
     // Note that we don't have to synchronize, as only this thread will
-    // ever modify the returned value and valueMap is a synchronizedMap.
-    Object value = valueMap.get(currentThread);
+    // ever modify the map.
+    Object value = map.get(key);
     if (value == null)
       {
         value = initialValue();
-        valueMap.put(currentThread, value == null ? NULL : value);
+        map.put(key, value == null ? NULL : value);
       }
     return value == NULL ? null : value;
   }
@@ -162,8 +163,9 @@
    */
   public void set(Object value)
   {
+    Map map = Thread.getThreadLocals();
     // Note that we don't have to synchronize, as only this thread will
-    // ever modify the returned value and valueMap is a synchronizedMap.
-    valueMap.put(Thread.currentThread(), value == null ? NULL : value);
+    // ever modify the map.
+    map.put(key, value == null ? NULL : value);
   }
 }



More information about the kaffe mailing list