Browse Source

Kill thread local leak

This commit modifies InjectorImpl to prevent a thread local leak in
certain web containers. This leak can arise when starting a node client
inside such a web container. The underlying issue is that the
ThreadLocal instance was created via an anonymous class. Such an
anonymous class has an implicit reference back to the InjectorImpl in
which it was created. The solution here is to not use an anonymous class
but instead just create the reference locally and set it on the thread
local.

Relates #17921
Jason Tedor 9 years ago
parent
commit
21b1da1bea

+ 6 - 7
core/src/main/java/org/elasticsearch/common/inject/InjectorImpl.java

@@ -84,12 +84,7 @@ class InjectorImpl implements Injector, Lookups {
         if (parent != null) {
             localContext = parent.localContext;
         } else {
-            localContext = new ThreadLocal<Object[]>() {
-                @Override
-                protected Object[] initialValue() {
-                    return new Object[1];
-                }
-            };
+            localContext = new ThreadLocal<>();
         }
     }
 
@@ -867,13 +862,17 @@ class InjectorImpl implements Injector, Lookups {
         return getProvider(type).get();
     }
 
-    final ThreadLocal<Object[]> localContext;
+    private 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 {
         Object[] reference = localContext.get();
+        if (reference == null) {
+            reference = new Object[1];
+            localContext.set(reference);
+        }
         if (reference[0] == null) {
             reference[0] = new InternalContext();
             try {