geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r638692 - in /geronimo/sandbox/concurrent/geronimo-concurrent-core/src: main/java/org/apache/geronimo/concurrent/harmony/ test/java/org/apache/geronimo/concurrent/executor/
Date Wed, 19 Mar 2008 03:34:09 GMT
Author: gawor
Date: Tue Mar 18 20:34:05 2008
New Revision: 638692

URL: http://svn.apache.org/viewvc?rev=638692&view=rev
Log:
ensure Future.get() can be called from ManagedTaskListener without causing a deadlock. Also,
improve reliability of tests

Modified:
    geronimo/sandbox/concurrent/geronimo-concurrent-core/src/main/java/org/apache/geronimo/concurrent/harmony/FutureTask.java
    geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedExecutorServiceTest.java
    geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedScheduledExecutorServiceTest.java
    geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/TestManagedTaskListener.java

Modified: geronimo/sandbox/concurrent/geronimo-concurrent-core/src/main/java/org/apache/geronimo/concurrent/harmony/FutureTask.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent-core/src/main/java/org/apache/geronimo/concurrent/harmony/FutureTask.java?rev=638692&r1=638691&r2=638692&view=diff
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent-core/src/main/java/org/apache/geronimo/concurrent/harmony/FutureTask.java
(original)
+++ geronimo/sandbox/concurrent/geronimo-concurrent-core/src/main/java/org/apache/geronimo/concurrent/harmony/FutureTask.java
Tue Mar 18 20:34:05 2008
@@ -305,12 +305,12 @@
             try {
                 taskStart();
                 runner = Thread.currentThread();
-                V v = callable.call();
+                V v = callable.call();                
+                innerSet(v);       
                 taskDone(null);
-                innerSet(v);                
-            } catch(Throwable ex) {
+            } catch(Throwable ex) {                
+                innerSetException(ex);    
                 taskDone(ex);
-                innerSetException(ex);                
             } 
         }
 
@@ -321,12 +321,13 @@
                 taskStart();
                 runner = Thread.currentThread();
                 callable.call(); // don't set result
-                runner = null;
+                runner = null;                
+                boolean rs = compareAndSetState(RUNNING, 0);
                 taskDone(null);
-                return compareAndSetState(RUNNING, 0);
-            } catch(Throwable ex) {
+                return rs;
+            } catch(Throwable ex) {                
+                innerSetException(ex);     
                 taskDone(ex);
-                innerSetException(ex);               
                 return false;
             } 
         }

Modified: geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedExecutorServiceTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedExecutorServiceTest.java?rev=638692&r1=638691&r2=638692&view=diff
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedExecutorServiceTest.java
(original)
+++ geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedExecutorServiceTest.java
Tue Mar 18 20:34:05 2008
@@ -28,6 +28,7 @@
 
 import javax.util.concurrent.ManagedExecutorService;
 
+import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.geronimo.concurrent.TestCallable;
@@ -36,6 +37,8 @@
 
 public abstract class BasicManagedExecutorServiceTest extends TestCase {
     
+    public static final int TIMEOUT = 5 * 1000;
+    
     public static final String NOT_EXPECTED = "unexpected data";
     
     protected ManagedExecutorService service;
@@ -99,6 +102,7 @@
         
         assertNull(f1.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task1.getList());
+        assertTrue("waiting for taskDone()", listener1.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
         compareCallbacks(callbacks1, listener1.getCallbacks(f1));
         
@@ -111,6 +115,7 @@
         
         assertEquals(value, f2.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task2.getList());  
+        assertTrue("waiting for taskDone()", listener2.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks2 = createCallbackInfo(f2);
         compareCallbacks(callbacks2, listener2.getCallbacks(f2));
         
@@ -122,11 +127,12 @@
         
         assertEquals(task3, f3.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task3.getList());  
+        assertTrue("waiting for taskDone()", listener3.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks3 = createCallbackInfo(f3);
         compareCallbacks(callbacks3, listener3.getCallbacks(f3));
     }
     
-    public void testFailSubmitWithListener() throws Exception {
+    public void testSubmitWithListenerFail() throws Exception {
         // test1
         TestRunnable task1 = new TestRunnable(true);
         TestManagedTaskListener listener1 = new TestManagedTaskListener();
@@ -141,7 +147,8 @@
                        e.getCause() instanceof IllegalStateException);
         }
         
-        assertEquals(Arrays.asList(expected), task1.getList());
+        assertEquals(Arrays.asList(expected), task1.getList());        
+        assertTrue("waiting for taskDone()", listener1.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
         compareCallbacks(callbacks1, listener1.getCallbacks(f1));
                 
@@ -161,6 +168,7 @@
         }
         
         assertEquals(Arrays.asList(expected), task2.getList());  
+        assertTrue("waiting for taskDone()", listener2.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks2 = createCallbackInfo(f2);
         compareCallbacks(callbacks2, listener2.getCallbacks(f2));
         
@@ -178,6 +186,7 @@
         }
         
         assertEquals(Arrays.asList(expected), task3.getList());  
+        assertTrue("waiting for taskDone()", listener3.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks3 = createCallbackInfo(f3);
         compareCallbacks(callbacks3, listener3.getCallbacks(f3));        
     }
@@ -239,12 +248,16 @@
         Future f1 = results.get(0);
         assertEquals(task1, f1.get(5, TimeUnit.SECONDS));
         assertEquals(Arrays.asList(expected), task1.getList()); 
-        List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
-        compareCallbacks(callbacks1, listener.getCallbacks(f1));
         
         Future f2 = results.get(1);
         assertEquals(task2, f2.get(5, TimeUnit.SECONDS));
-        assertEquals(Arrays.asList(expected), task2.getList());  
+        assertEquals(Arrays.asList(expected), task2.getList());
+                
+        assertTrue("waiting for taskDone()", listener.waitForDone(2, TIMEOUT));
+        
+        List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
+        compareCallbacks(callbacks1, listener.getCallbacks(f1));        
+  
         List<TestManagedTaskListener.CallbackInfo> callbacks2 = createCallbackInfo(f2);
         compareCallbacks(callbacks2, listener.getCallbacks(f2));
     }
@@ -297,6 +310,7 @@
         
         assertNull(f1.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task1.getList());
+        assertTrue("waiting for taskDone()", listener1.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
         compareCallbacks(callbacks1, listener1.getCallbacks(f1));
         
@@ -310,6 +324,7 @@
         
         assertEquals(value, f2.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task2.getList());  
+        assertTrue("waiting for taskDone()", listener2.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks2 = createCallbackInfo(f2);
         compareCallbacks(callbacks2, listener2.getCallbacks(f2));
         
@@ -322,6 +337,7 @@
         
         assertEquals(task3, f3.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task3.getList());  
+        assertTrue("waiting for taskDone()", listener3.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks3 = createCallbackInfo(f3);
         compareCallbacks(callbacks3, listener3.getCallbacks(f3));
     }   
@@ -389,6 +405,111 @@
         assertTrue(callback.getException() instanceof RejectedExecutionException);
     }
     
+    /**
+     * Tests whether calling Future.get() from within ManagedTaskLister.taskDone() work 
+     * as expected (i.e. does not cause a deadlock).
+     */
+    public void testFutureInListenerDone() throws Exception {
+        TestCallable task = new TestCallable(2 * 1000);
+        
+        FutureDoneTastListener listener = new FutureDoneTastListener();
+        
+        Future f1 = service.submit(task, listener);
+        
+        assertEquals(task, f1.get());
+
+        assertTrue("waiting for taskDone()", listener.waitForDone(TIMEOUT));
+        assertEquals(Arrays.asList(expected), task.getList());       
+        List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
+        compareCallbacks(callbacks1, listener.getCallbacks(f1));
+                
+        assertEquals(task, listener.getFutureResult());
+        assertEquals(null, listener.getFutureException());               
+    }
+    
+    /**
+     * Tests whether calling Future.get() from within ManagedTaskLister.taskAbort() work

+     * as expected (i.e. does not cause a deadlock).
+     */
+    public void testFutureInListenerAbort() throws Exception {
+        TestCallable task = new TestCallable(10 * 1000);
+        
+        FutureAbortTastListener listener = new FutureAbortTastListener();
+        
+        Future f1 = service.submit(task, listener);
+        
+        Thread.sleep(5 * 1000);
+        f1.cancel(true);
+        try {
+            f1.get();
+            fail("Did not throw exception");
+        } catch (CancellationException e) {
+            // expected
+        }
+
+        assertTrue("waiting for taskDone()", listener.waitForDone(TIMEOUT));
+        assertTrue(task.getList().isEmpty()); // it should be empty as the task got cancelled
      
+        List<TestManagedTaskListener.CallbackInfo> callbacks1 = createAbortCallbackInfoV1(f1);
+        try {
+            compareCallbacks(callbacks1, listener.getCallbacks(f1));
+        } catch (AssertionFailedError e) {
+            callbacks1 = createAbortCallbackInfoV2(f1);
+            compareCallbacks(callbacks1, listener.getCallbacks(f1));
+        }
+                
+        assertEquals(null, listener.getFutureResult());       
+        assertTrue(listener.getFutureException() instanceof  CancellationException);    
         
+    }
+    
+    private static class FutureDoneTastListener extends TestManagedTaskListener {
+        private Object result;
+        private Throwable exception;
+        
+        public Object getFutureResult() {
+            return this.result;
+        }
+        
+        public Throwable getFutureException() {
+            return this.exception;
+        }
+        
+        @Override
+        public void taskDone(Future<?> arg0, ManagedExecutorService arg1, Throwable
arg2) {
+            try {
+                this.result = arg0.get();
+            } catch (Throwable e) {
+                this.exception = e;
+            } 
+            super.taskDone(arg0, arg1, arg2);         
+        }
+    }
+    
+    private static class FutureAbortTastListener extends TestManagedTaskListener {
+        private Object result;
+        private Throwable exception;
+        
+        public Object getFutureResult() {
+            return this.result;
+        }
+        
+        public Throwable getFutureException() {
+            return this.exception;
+        }
+        
+        @Override
+        public void taskAborted(Future<?> arg0, ManagedExecutorService arg1, Throwable
arg2) {
+            try {
+                this.result = arg0.get();
+            } catch (Throwable e) {
+                this.exception = e;
+            }
+            super.taskAborted(arg0, arg1, arg2);          
+        }
+    }
+    
+    
+    // common functions    
+    
     protected void checkListenerBasics(Future expectedFuture,
                                        List<TestManagedTaskListener.CallbackInfo> callbacks)
throws Exception {
         for (int i = 0; i < callbacks.size(); i++) {
@@ -408,15 +529,18 @@
     
     protected void compareCallbacks(List<TestManagedTaskListener.CallbackInfo> expectedCallbacks,
                                     List<TestManagedTaskListener.CallbackInfo> actualCallbacks)
throws Exception {
-        System.out.println("Expected");
-        System.out.println(expectedCallbacks);
-        System.out.println("Actual");
-        System.out.println(actualCallbacks);
+        //System.out.println("Expected");
+        //System.out.println(expectedCallbacks);
+        //System.out.println("Actual");
+        //System.out.println(actualCallbacks);
         
         assertEquals(expectedCallbacks.size(), actualCallbacks.size());
         for (int i = 0; i < expectedCallbacks.size(); i++) {
             TestManagedTaskListener.CallbackInfo expectedCallbackInfo = expectedCallbacks.get(i);
             TestManagedTaskListener.CallbackInfo actaulCallbackInfo = actualCallbacks.get(i);
+          
+            System.out.println("Expected : " + expectedCallbackInfo);
+            System.out.println("Actual   : " + actaulCallbackInfo);
             
             assertEquals(expectedCallbackInfo.getCallback(), 
                          actaulCallbackInfo.getCallback());
@@ -428,7 +552,7 @@
                          actaulCallbackInfo.getData());
         }
     }
-    
+            
     protected List<TestManagedTaskListener.CallbackInfo> createCallbackInfo(Future
future) {
         return createCallbackInfo(future, 1);
     }
@@ -452,6 +576,26 @@
         List<TestManagedTaskListener.CallbackInfo> callbacks = 
             new ArrayList<TestManagedTaskListener.CallbackInfo>();
         addCancelCallbackInfo(future, callbacks);
+        return callbacks;
+    }
+    
+    protected List<TestManagedTaskListener.CallbackInfo> createAbortCallbackInfoV1(Future
future) {
+        List<TestManagedTaskListener.CallbackInfo> callbacks = 
+            new ArrayList<TestManagedTaskListener.CallbackInfo>();
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.SUBMITTED,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.STARTING,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.ABORTED,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.DONE,
future, service, null, expected));
+        return callbacks;
+    }
+    
+    protected List<TestManagedTaskListener.CallbackInfo> createAbortCallbackInfoV2(Future
future) {
+        List<TestManagedTaskListener.CallbackInfo> callbacks = 
+            new ArrayList<TestManagedTaskListener.CallbackInfo>();
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.SUBMITTED,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.STARTING,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.DONE,
future, service, null, expected));
+        callbacks.add(new TestManagedTaskListener.CallbackInfo(TestManagedTaskListener.Callbacks.ABORTED,
future, service, null, expected));
         return callbacks;
     }
     

Modified: geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedScheduledExecutorServiceTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedScheduledExecutorServiceTest.java?rev=638692&r1=638691&r2=638692&view=diff
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedScheduledExecutorServiceTest.java
(original)
+++ geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/BasicManagedScheduledExecutorServiceTest.java
Tue Mar 18 20:34:05 2008
@@ -59,6 +59,7 @@
         
         assertNull(f1.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task1.getList());
+        assertTrue("waiting for taskDone()", listener1.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks1 = createCallbackInfo(f1);
         compareCallbacks(callbacks1, listener1.getCallbacks(f1));
                    
@@ -70,6 +71,7 @@
         
         assertEquals(task2, f2.get(5, TimeUnit.SECONDS));        
         assertEquals(Arrays.asList(expected), task2.getList());
+        assertTrue("waiting for taskDone()", listener2.waitForDone(TIMEOUT));
         List<TestManagedTaskListener.CallbackInfo> callbacks2 = createCallbackInfo(f2);
         compareCallbacks(callbacks2, listener2.getCallbacks(f2));
     }
@@ -178,7 +180,7 @@
         
         f1.cancel(true);
         
-        Thread.sleep(1000 * 5);
+        assertTrue("waiting for taskDone()", listener.waitForDone(TIMEOUT));
                 
         List<TestManagedTaskListener.CallbackInfo> callbacks = createCancelCallbackInfo(f1);
         compareCallbacks(callbacks, listener.getCallbacks());              
@@ -195,7 +197,7 @@
         
         f1.cancel(true);
         
-        Thread.sleep(1000 * 5);
+        assertTrue("waiting for taskDone()", listener.waitForDone(TIMEOUT));
                 
         List<TestManagedTaskListener.CallbackInfo> callbacks = createCancelCallbackInfo(f1);
         compareCallbacks(callbacks, listener.getCallbacks());
@@ -222,6 +224,8 @@
             // that's what we expect
         }
         
+        assertTrue("waiting for taskDone()", listener.waitForDone(3, TIMEOUT));
+        
         assertFalse(f1.isDone());
         assertFalse(f1.isCancelled());
         
@@ -235,8 +239,8 @@
         
         assertTrue(f1.isDone());
         assertTrue(f1.isCancelled());
-        
-        Thread.sleep(1000 * 10);
+                
+        assertTrue("waiting for taskDone()", listener.waitForDone(2 * TIMEOUT));
         
         List<TestManagedTaskListener.CallbackInfo> callbacks = createCallbackInfo(f1,
2);
         addSkippedCallbackInfo(f1, callbacks);

Modified: geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/TestManagedTaskListener.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/TestManagedTaskListener.java?rev=638692&r1=638691&r2=638692&view=diff
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/TestManagedTaskListener.java
(original)
+++ geronimo/sandbox/concurrent/geronimo-concurrent-core/src/test/java/org/apache/geronimo/concurrent/executor/TestManagedTaskListener.java
Tue Mar 18 20:34:05 2008
@@ -20,6 +20,8 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Future;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 
 import javax.util.concurrent.ManagedExecutorService;
 import javax.util.concurrent.ManagedTaskListener;
@@ -118,6 +120,8 @@
     private List<CallbackInfo> callbacks = Collections
             .synchronizedList(new ArrayList<CallbackInfo>());
 
+    private Semaphore semaphore = new Semaphore(0);
+    
     public List<CallbackInfo> getCallbacks() {
         return this.callbacks;
     }
@@ -141,7 +145,8 @@
 
     public void taskDone(Future<?> arg0, ManagedExecutorService arg1, Throwable arg2)
{
         Object data = TestContextHandler.getCurrentObject();
-        callbacks.add(new CallbackInfo(Callbacks.DONE, arg0, arg1, arg2, data));
+        callbacks.add(new CallbackInfo(Callbacks.DONE, arg0, arg1, arg2, data)); 
+        semaphore.release();
     }
 
     public void taskStarting(Future<?> arg0, ManagedExecutorService arg1) {
@@ -154,4 +159,16 @@
         callbacks.add(new CallbackInfo(Callbacks.SUBMITTED, arg0, arg1, null, data));
     }
     
+    public boolean waitForDone(int timeout) throws InterruptedException {
+        return semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+    }
+    
+    public boolean waitForDone(int permits, int timeout) throws InterruptedException {
+        for (int i = 0; i < permits; i++) {
+            if (!semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }



Mime
View raw message