Author: limpbizkit
Date: Wed May  6 11:14:32 2009
New Revision: 940

Modified:
    trunk/src/com/google/inject/InjectorImpl.java
    trunk/src/com/google/inject/internal/InternalContext.java

Log:
patch from mcculls:
Rolling back one of the optimizations to avoid leaving garbage behind in a  
ThreadLocal. The extra reference can cause the thread to strongly hold the  
injector, which is bad for application unloading.

Regrettably, this costs about 12% throughput. Even so, we're still creating  
almost a million objects per second on my laptop, so we're still good.

Modified: trunk/src/com/google/inject/InjectorImpl.java
==============================================================================
--- trunk/src/com/google/inject/InjectorImpl.java       (original)
+++ trunk/src/com/google/inject/InjectorImpl.java       Wed May  6 11:14:32 2009
@@ -79,9 +79,9 @@
      if (parent != null) {
        localContext = parent.localContext;
      } else {
-      localContext = new ThreadLocal<InternalContext>() {
-        protected InternalContext initialValue() {
-          return new InternalContext();
+      localContext = new ThreadLocal<Object[]>() {
+        protected Object[] initialValue() {
+          return new Object[1];
          }
        };
      }
@@ -793,16 +793,22 @@
      return getProvider(type).get();
    }

-  final ThreadLocal<InternalContext> localContext;
+  final ThreadLocal<Object[]> localContext;

    /** Looks up thread local context. Creates (and removes) a new context  
if necessary. */
    <T> T callInContext(ContextualCallable<T> callable) throws  
ErrorsException {
-    InternalContext reference = localContext.get();
-    reference.acquire();
-    try {
-      return callable.call(reference);
-    } finally {
-      reference.release();
+    Object[] reference = localContext.get();
+    if (reference[0] == null) {
+      reference[0] = new InternalContext();
+      try {
+        return callable.call((InternalContext)reference[0]);
+      } finally {
+        // Only clear the context if this call created it.
+        reference[0] = null;
+      }
+    } else {
+      // Someone else will clean up this context.
+      return callable.call((InternalContext)reference[0]);
      }
    }


Modified: trunk/src/com/google/inject/internal/InternalContext.java
==============================================================================
--- trunk/src/com/google/inject/internal/InternalContext.java   (original)
+++ trunk/src/com/google/inject/internal/InternalContext.java   Wed May  6  
11:14:32 2009
@@ -16,7 +16,6 @@

  package com.google.inject.internal;

-import static com.google.inject.internal.Preconditions.checkState;
  import com.google.inject.spi.Dependency;
  import java.util.Map;

@@ -30,7 +29,6 @@

    private Map<Object, ConstructionContext<?>> constructionContexts =  
Maps.newHashMap();
    private Dependency dependency;
-  private int acquired = 0;

    @SuppressWarnings("unchecked")
    public <T> ConstructionContext<T> getConstructionContext(Object key) {
@@ -41,19 +39,6 @@
        constructionContexts.put(key, constructionContext);
      }
      return constructionContext;
-  }
-
-  public void acquire() {
-    acquired++;
-  }
-
-  public void release() {
-    checkState(acquired > 0);
-    acquired--;
-    if (acquired == 0) {
-      constructionContexts.clear();
-      dependency = null;
-    }
    }

    public Dependency getDependency() {

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to