[picocontainer-scm] [scm-git][2] Fixed threading failure.

Michael Rimov <git-yCVjj/[email protected]> Sat, 30 Jun 2012 14:46:08 -0500 (CDT)
Newsgroups gmane.comp.java.picocontainer.cvs
Message-ID <[email protected]>
commit b192cfc8112941492ccfa2407704954718202a52
Author:     Michael Rimov <[email protected]>
AuthorDate: Fri Jun 29 18:03:46 2012 -0700
Commit:     Michael Rimov <[email protected]>
CommitDate: Fri Jun 29 18:03:46 2012 -0700

    Fixed threading failure.

diff --git a/pico/container/src/java/org/picocontainer/behaviors/ThreadCaching.java b/pico/container/src/java/org/picocontainer/behaviors/ThreadCaching.java
index eaed493..332123a 100644
--- a/pico/container/src/java/org/picocontainer/behaviors/ThreadCaching.java
+++ b/pico/container/src/java/org/picocontainer/behaviors/ThreadCaching.java
@@ -51,7 +51,6 @@ public class ThreadCaching extends AbstractBehavior {
      *
      * @author Paul Hammant
      */
-    @SuppressWarnings("serial")
     public static final class ThreadCached<T> extends Storing.Stored<T> {
 
         public ThreadCached(ComponentAdapter<T> delegate) {
diff --git a/pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java b/pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java
index 4cc26e8..a7c394f 100644
--- a/pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java
+++ b/pico/container/src/java/org/picocontainer/injectors/IterativeInjector.java
@@ -41,7 +41,7 @@ public abstract class IterativeInjector<T> extends AbstractInjector<T> {
     protected transient Annotation[] bindings;
 
     private transient Paranamer paranamer;
-    private transient boolean initialized;
+    private volatile transient boolean initialized;
     /**
      * Constructs a IterativeInjector
      *
@@ -230,9 +230,9 @@ public abstract class IterativeInjector<T> extends AbstractInjector<T> {
     public Object decorateComponentInstance(final PicoContainer container, final Type into, final T instance) {
         if (instantiationGuard == null) {
             instantiationGuard = new ThreadLocalCyclicDependencyGuard() {
-                public Object run(Object inst) {
+                public Object run(final Object inst) {
                     final Parameter[] matchingParameters = getMatchingParameterListForSetters(guardedContainer);
-                    return decorateComponentInstance(matchingParameters, currentMonitor(), instance, container, guardedContainer, into);
+                    return decorateComponentInstance(matchingParameters, currentMonitor(), inst, container, guardedContainer, into);
                 }
             };
         }
diff --git a/pico/container/src/test/org/picocontainer/behaviors/SynchronizedTestCase.java b/pico/container/src/test/org/picocontainer/behaviors/SynchronizedTestCase.java
index 49017a7..a7c541e 100644
--- a/pico/container/src/test/org/picocontainer/behaviors/SynchronizedTestCase.java
+++ b/pico/container/src/test/org/picocontainer/behaviors/SynchronizedTestCase.java
@@ -114,7 +114,10 @@ public class SynchronizedTestCase {
     }
 
     @Test public void testRaceConditionIsNotHandledWithoutSynchronizedComponentAdapter() throws InterruptedException {
-        ComponentAdapter<Blocker> componentAdapter = new Caching.Cached<Blocker>(new ConstructorInjection.ConstructorInjector<Blocker>(new NullComponentMonitor(), false, "key", Blocker.class, null));
+        ComponentAdapter<Blocker> componentAdapter = new Caching.Cached<Blocker>(new ConstructorInjection.ConstructorInjector<Blocker>(new NullComponentMonitor(), 
+        		false, 
+        		"key", 
+        		Blocker.class, null));
         initTest(componentAdapter);
 
         assertNull(runner[0].exception);
diff --git a/pico/container/src/test/org/picocontainer/behaviors/ThreadCachingTestCase.java b/pico/container/src/test/org/picocontainer/behaviors/ThreadCachingTestCase.java
index 2c57974..f948970 100644
--- a/pico/container/src/test/org/picocontainer/behaviors/ThreadCachingTestCase.java
+++ b/pico/container/src/test/org/picocontainer/behaviors/ThreadCachingTestCase.java
@@ -44,23 +44,18 @@ public class ThreadCachingTestCase {
 
     public static class Qux {
 
-        private static final Object lock = new Object();
-
         private static int CTR;
 
         private int inst;
 
         public Qux(StringBuilder sb) {
-            synchronized (lock) {
-                inst = CTR++;
+                inst = CTR;
+                CTR++;
                 sb.append("!").append(inst).append(" ");
             }
-        }
         public void setStringBuilder(StringBuilder sb) {
-            synchronized (lock) {
                 sb.append("<").append(inst).append(" ");
             }
-        }
 
         @Override
         public String toString() {
@@ -149,13 +144,14 @@ public class ThreadCachingTestCase {
         assertEquals("ThreadCached:LifecycleAdapter:ConstructorInjector-class org.picocontainer.behaviors.ThreadCachingTestCase$Foo", child.getComponentAdapter(Foo.class).toString());
     }
 
-    @Test public void testThatTwoThreadsHaveSeparatedCacheValuesWithCompositeInjection() {
+    @Test public void testThatTwoThreadsHaveSeparatedCacheValuesWithCompositeInjection() throws InterruptedException {
 
         final Qux[] quxs = new Qux[4];
 
         DefaultPicoContainer parent = new DefaultPicoContainer(new Caching());
-        final DefaultPicoContainer child = new DefaultPicoContainer(parent, new ThreadCaching().wrap(
-                new CompositeInjection(new ConstructorInjection(), new SetterInjection())));
+        final DefaultPicoContainer child = new DefaultPicoContainer(parent, new NullLifecycleStrategy(),
+        		new ThreadCaching().wrap(new CompositeInjection(new ConstructorInjection(), new SetterInjection())));
+
 
         parent.addComponent(StringBuilder.class);
         child.addComponent(Qux.class);
@@ -169,13 +165,19 @@ public class ThreadCachingTestCase {
                 quxs[3] = child.getComponent(Qux.class);
             }
         };
+        
         thread.start();
-        quxs[2] = child.getComponent(Qux.class);
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
+        
+        synchronized(this) {
+        	thread.join();
         }
 
+        
+        assertFalse(thread.isAlive());
+        
+        
+        quxs[2] = child.getComponent(Qux.class);
+
         assertNotNull(quxs[0]);
         assertNotNull(quxs[1]);
         assertNotNull(quxs[2]);
@@ -184,7 +186,8 @@ public class ThreadCachingTestCase {
         assertEquals(quxs[1],quxs[3]);
         assertFalse(quxs[0] == quxs[1]);
         assertEquals("!0 <0 !1 <1", sb.toString().trim());
-        assertEquals("ThreadCached:CompositeInjector(ConstructorInjector+SetterInjector)-class org.picocontainer.behaviors.ThreadCachingTestCase$Qux", child.getComponentAdapter(Qux.class).toString());
+        assertEquals("ThreadCached:CompositeInjector(ConstructorInjector+SetterInjector)" +
+        		"-class org.picocontainer.behaviors.ThreadCachingTestCase$Qux", child.getComponentAdapter(Qux.class).toString());
     }
 
     @Test public void testThatTwoThreadsHaveSeparatedCacheValuesWithInstanceRegistrationAndClassLoadingPicoContainer() {