[jboss-cvs] JBossAS SVN: r92050 - projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Aug 6 01:00:36 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-08-06 01:00:35 -0400 (Thu, 06 Aug 2009)
New Revision: 92050

Added:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutorService.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutorService.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingRunnable.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingScheduledExecutorService.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/Dependency.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DependencyTaskBuilder.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingDirectExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingRunnable.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/TaskNotifier.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadLocalResetter.java
Removed:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedScheduledExecutorService.java
Modified:
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/AtomicArray.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/BalancingExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/CleanupExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingWrappingExecutor.java
   projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
Log:
Add task notifiers; factor out more inner classes; clean up class names and make them specific; add executor-based task dependency mechanism; other minor fixes and cleanups

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/AtomicArray.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/AtomicArray.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/AtomicArray.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -41,19 +41,19 @@
 public final class AtomicArray<T, V> {
 
     private final AtomicReferenceFieldUpdater<T, V[]> updater;
-    private final Class<V> componentType;
     private final V[] emptyArray;
+    private final Creator<V> creator;
 
     /**
      * Construct an instance.
      *
      * @param updater the field updater
-     * @param componentType the component class
+     * @param creator the array creator
      */
-    public AtomicArray(AtomicReferenceFieldUpdater<T, V[]> updater, Class<V> componentType) {
+    private AtomicArray(AtomicReferenceFieldUpdater<T, V[]> updater, Creator<V> creator) {
         this.updater = updater;
-        this.componentType = componentType;
-        emptyArray = newInstance(componentType, 0);
+        this.creator = creator;
+        emptyArray = creator.create(0);
     }
 
     /**
@@ -66,10 +66,23 @@
      * @return the new instance
      */
     public static <T, V> AtomicArray<T, V> create(AtomicReferenceFieldUpdater<T, V[]> updater, Class<V> componentType) {
-        return new AtomicArray<T,V>(updater, componentType);
+        return new AtomicArray<T,V>(updater, new ReflectCreator<V>(componentType));
     }
 
     /**
+     * Convenience method to create an instance.
+     *
+     * @param updater the field updater
+     * @param creator the array creator
+     * @param <T> the type which contains the target field
+     * @param <V> the array value type
+     * @return the new instance
+     */
+    public static <T, V> AtomicArray<T, V> create(AtomicReferenceFieldUpdater<T, V[]> updater, Creator<V> creator) {
+        return new AtomicArray<T,V>(updater, creator);
+    }
+
+    /**
      * Convenience method to set the field value to the empty array.  Empty array instances are shared.
      *
      * @param instance the instance holding the field
@@ -99,8 +112,8 @@
     }
 
     @SuppressWarnings({ "unchecked" })
-    private static <V> V[] copyOf(final Class<V> componentType, V[] old, int newLen) {
-        final V[] target = newInstance(componentType, newLen);
+    private static <V> V[] copyOf(final AtomicArray.Creator<V> creator, V[] old, int newLen) {
+        final V[] target = creator.create(newLen);
         System.arraycopy(old, 0, target, 0, Math.min(old.length, newLen));
         return target;
     }
@@ -116,7 +129,7 @@
         for (;;) {
             final V[] oldVal = updater.get(instance);
             final int oldLen = oldVal.length;
-            final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
+            final V[] newVal = copyOf(creator, oldVal, oldLen + 1);
             newVal[oldLen] = value;
             if (updater.compareAndSet(instance, oldVal, newVal)) {
                 return;
@@ -151,7 +164,7 @@
                     }
                 }
             }
-            final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
+            final V[] newVal = copyOf(creator, oldVal, oldLen + 1);
             newVal[oldLen] = value;
             if (updater.compareAndSet(instance, oldVal, newVal)) {
                 return true;
@@ -195,7 +208,7 @@
                 if (index == -1) {
                     return false;
                 }
-                final V[] newVal = newInstance(componentType, oldLen - 1);
+                final V[] newVal = creator.create(oldLen - 1);
                 System.arraycopy(oldVal, 0, newVal, 0, index);
                 System.arraycopy(oldVal, index + 1, newVal, index, oldLen - index - 1);
                 if (updater.compareAndSet(instance, oldVal, newVal)) {
@@ -247,7 +260,7 @@
                 if (newLen == 0) {
                     newVal = emptyArray;
                 } else {
-                    newVal = newInstance(componentType, newLen);
+                    newVal = creator.create(newLen);
                     for (int i = 0, j = 0; i < oldLen; i ++) {
                         if (! removeSlots[i]) {
                             newVal[j++] = oldVal[i];
@@ -274,7 +287,7 @@
             final V[] oldVal = updater.get(instance);
             final int oldLen = oldVal.length;
             final int pos = insertionPoint(Arrays.binarySearch(oldVal, value, comparator));
-            final V[] newVal = newInstance(componentType, oldLen + 1);
+            final V[] newVal = creator.create(oldLen + 1);
             System.arraycopy(oldVal, 0, newVal, 0, pos);
             newVal[pos] = value;
             System.arraycopy(oldVal, pos, newVal, pos + 1, oldLen - pos);
@@ -300,7 +313,7 @@
             if (pos < 0) {
                 return false;
             }
-            final V[] newVal = newInstance(componentType, oldLen + 1);
+            final V[] newVal = creator.create(oldLen + 1);
             System.arraycopy(oldVal, 0, newVal, 0, pos);
             newVal[pos] = value;
             System.arraycopy(oldVal, pos, newVal, pos + 1, oldLen - pos);
@@ -330,7 +343,7 @@
                 if (pos < 0) {
                     return false;
                 }
-                final V[] newVal = newInstance(componentType, oldLen - 1);
+                final V[] newVal = creator.create(oldLen - 1);
                 System.arraycopy(oldVal, 0, newVal, 0, pos);
                 System.arraycopy(oldVal, pos + 1, newVal, pos, oldLen - pos - 1);
                 if (updater.compareAndSet(instance, oldVal, newVal)) {
@@ -373,4 +386,20 @@
             return (V[]) Array.newInstance(componentType, length);
         }
     }
+
+    public interface Creator<V> {
+        V[] create(int len);
+    }
+
+    private static final class ReflectCreator<V> implements Creator<V> {
+        private final Class<V> type;
+
+        public ReflectCreator(final Class<V> type) {
+            this.type = type;
+        }
+
+        public V[] create(final int len) {
+            return newInstance(type, len);
+        }
+    }
 }

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/BalancingExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/BalancingExecutor.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/BalancingExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -40,7 +40,11 @@
     private final AtomicInteger seq = new AtomicInteger();
     private final Lock writeLock = new ReentrantLock();
 
-    private static final AtomicArray<BalancingExecutor, Executor> executorsUpdater = AtomicArray.create(newUpdater(BalancingExecutor.class, Executor[].class, "executors"), Executor.class);
+    private static final AtomicArray<BalancingExecutor, Executor> executorsUpdater = AtomicArray.create(newUpdater(BalancingExecutor.class, Executor[].class, "executors"), new AtomicArray.Creator<Executor>() {
+        public Executor[] create(final int len) {
+            return new Executor[len];
+        }
+    });
 
     /**
      * Construct a new instance.

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/CleanupExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/CleanupExecutor.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/CleanupExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -26,6 +26,7 @@
 
     private final Runnable cleaner;
     private final DirectExecutor delegate;
+    private static final DirectExecutor CLEANER_EXECUTOR = JBossExecutors.exceptionLoggingExecutor(JBossExecutors.directExecutor());
 
     CleanupExecutor(final Runnable cleaner, final DirectExecutor delegate) {
         this.cleaner = cleaner;
@@ -36,7 +37,7 @@
         try {
             delegate.execute(command);
         } finally {
-            cleaner.run();
+            CLEANER_EXECUTOR.execute(cleaner);
         }
     }
 

Copied: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutor.java (from rev 91835, projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java)
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutor.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A direct executor that simply delegates to another direct executor.  Use instances of this class to hide extra methods on
+ * another executor.
+ */
+class DelegatingDirectExecutor extends DelegatingExecutor implements DirectExecutor {
+
+    DelegatingDirectExecutor(final DirectExecutor delegate) {
+        super(delegate);
+    }
+
+    protected DirectExecutor getDelegate() {
+        return (DirectExecutor) super.getDelegate();
+    }
+}

Copied: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutorService.java (from rev 91835, projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java)
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutorService.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingDirectExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A {@code DirectExecutor} version of {@code ProtectedExecutorService}.
+ */
+class DelegatingDirectExecutorService extends DelegatingExecutorService implements DirectExecutorService {
+    DelegatingDirectExecutorService(final DirectExecutor delegate) {
+        super(delegate);
+    }
+}

Copied: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutor.java (from rev 91883, projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java)
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutor.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.Executor;
+
+/**
+ * An executor that simply delegates to another executor.  Use instances of this class to hide extra methods on
+ * another executor.
+ */
+class DelegatingExecutor implements Executor {
+    private final Executor delegate;
+
+    DelegatingExecutor(final Executor delegate) {
+        this.delegate = delegate;
+    }
+
+    protected Executor getDelegate() {
+        return delegate;
+    }
+
+    /**
+     * Execute a task by passing it to the delegate executor.
+     *
+     * @param command the task
+     */
+    public void execute(final Runnable command) {
+        delegate.execute(command);
+    }
+
+    public String toString() {
+        return String.format("%s -> %s", super.toString(), delegate);
+    }
+}

Copied: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutorService.java (from rev 91879, projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java)
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutorService.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.Executor;
+import java.util.List;
+
+/**
+ * An implementation of {@code ExecutorService} that delegates to the real executor, while disallowing termination.
+ */
+class DelegatingExecutorService extends AbstractExecutorService implements ExecutorService {
+    private final Executor delegate;
+
+    DelegatingExecutorService(final Executor delegate) {
+        this.delegate = delegate;
+    }
+
+    public void execute(final Runnable command) {
+        delegate.execute(command);
+    }
+
+    public boolean isShutdown() {
+        // container managed executors are never shut down from the application's perspective
+        return false;
+    }
+
+    public boolean isTerminated() {
+        // container managed executors are never shut down from the application's perspective
+        return false;
+    }
+
+    public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
+        unit.sleep(timeout);
+        return false;
+    }
+
+    public void shutdown() {
+        throw new SecurityException("shutdown() not allowed on container-managed executor");
+    }
+
+    public List<Runnable> shutdownNow() {
+        throw new SecurityException("shutdownNow() not allowed on container-managed executor");
+    }
+
+    public static ExecutorService directExecutorService() {
+        return new DelegatingExecutorService(JBossExecutors.directExecutor());
+    }
+
+    public String toString() {
+        return String.format("%s -> %s", super.toString(), delegate);
+    }
+}

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingRunnable.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingRunnable.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingRunnable.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+class DelegatingRunnable implements Runnable {
+    private final Runnable delegate;
+
+    DelegatingRunnable(final Runnable delegate) {
+        this.delegate = delegate;
+    }
+
+    protected Runnable getDelegate() {
+        return delegate;
+    }
+
+    public void run() {
+        delegate.run();
+    }
+
+    public String toString() {
+        return String.format("%s -> %s", super.toString(), delegate);
+    }
+}

Copied: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingScheduledExecutorService.java (from rev 91835, projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedScheduledExecutorService.java)
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingScheduledExecutorService.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingScheduledExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.Callable;
+
+/**
+ * An implementation of {@code ScheduledExecutorService} that delegates to the real executor, while disallowing termination.
+ */
+class DelegatingScheduledExecutorService extends DelegatingExecutorService implements ScheduledExecutorService {
+    private final ScheduledExecutorService delegate;
+
+    DelegatingScheduledExecutorService(final ScheduledExecutorService delegate) {
+        super(delegate);
+        this.delegate = delegate;
+    }
+
+    public ScheduledFuture<?> schedule(final Runnable command, final long delay, final TimeUnit unit) {
+        return delegate.schedule(command, delay, unit);
+    }
+
+    public <V> ScheduledFuture<V> schedule(final Callable<V> callable, final long delay, final TimeUnit unit) {
+        return delegate.schedule(callable, delay, unit);
+    }
+
+    public ScheduledFuture<?> scheduleAtFixedRate(final Runnable command, final long initialDelay, final long period, final TimeUnit unit) {
+        return delegate.scheduleAtFixedRate(command, initialDelay, period, unit);
+    }
+
+    public ScheduledFuture<?> scheduleWithFixedDelay(final Runnable command, final long initialDelay, final long delay, final TimeUnit unit) {
+        return delegate.scheduleWithFixedDelay(command, initialDelay, delay, unit);
+    }
+}
\ No newline at end of file

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingWrappingExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingWrappingExecutor.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DelegatingWrappingExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -25,7 +25,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 
-class DelegatingWrappingExecutor extends ProtectedExecutor implements WrappingExecutor {
+class DelegatingWrappingExecutor extends DelegatingExecutor implements WrappingExecutor {
 
     DelegatingWrappingExecutor(final Executor delegate) {
         super(delegate);

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/Dependency.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/Dependency.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/Dependency.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,181 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import org.jboss.logging.Logger;
+
+/**
+ * A task which depends on other tasks, and which may have tasks depending upon it.  Such a task is automatically
+ * run when using a provided executor when all its dependencies are satisfied.
+ */
+public final class Dependency {
+    private static final Logger log = Logger.getLogger(Dependency.class);
+
+    private static final AtomicIntegerFieldUpdater<Dependency> depUpdater = AtomicIntegerFieldUpdater.newUpdater(Dependency.class, "remainingDependencies");
+
+    /**
+     * Number of dependencies left before this task can start.
+     */
+    @SuppressWarnings({ "UnusedDeclaration" })
+    private volatile int remainingDependencies;
+
+    private final Executor executor;
+    private final Object lock = new Object();
+    private Runner runner;
+    private State state;
+
+    Dependency(final Executor executor, final Runnable runnable, final int initialDepCount) {
+        this.executor = executor;
+        synchronized (lock) {
+            runner = new Runner(runnable);
+            state = State.WAITING;
+            remainingDependencies = initialDepCount;
+        }
+    }
+
+    void addDependent(Dependency task) {
+        synchronized (lock) {
+            switch (state) {
+                case WAITING:
+                case RUNNING: runner.dependents.add(task); return;
+                case FAILED: return;
+                case DONE: break; // fall out of lock
+                default: throw new IllegalStateException();
+            }
+        }
+        task.dependencyFinished();
+    }
+
+    void dependencyFinished() {
+        final AtomicIntegerFieldUpdater<Dependency> updater = depUpdater;
+        final int res = updater.decrementAndGet(this);
+        if (res == 0) {
+            synchronized (lock) {
+                try {
+                    executor.execute(runner);
+                    state = State.RUNNING;
+                } catch (RejectedExecutionException e) {
+                    log.errorf(e, "Error submitting task %s to executor", runner.runnable);
+                    state = State.FAILED;
+                    final Dependency.Runner runner = this.runner;
+                    runner.runnable = null;
+                    runner.dependents = null;
+                    this.runner = null;
+                }
+            }
+        } else if (res < 0) {
+            // oops?
+            updater.incrementAndGet(this);
+        }
+    }
+
+    private void dependencyFailed() {
+        final AtomicIntegerFieldUpdater<Dependency> updater = depUpdater;
+        final int res = updater.decrementAndGet(this);
+        if (res == 0) {
+            synchronized (lock) {
+                state = State.FAILED;
+                final Dependency.Runner runner = this.runner;
+                runner.runnable = null;
+                runner.dependents = null;
+                this.runner = null;
+            }
+        } else if (res < 0) {
+            // oops?
+            updater.incrementAndGet(this);
+        }
+    }
+
+    private class Runner implements Runnable {
+
+        private List<Dependency> dependents = new ArrayList<Dependency>();
+        private Runnable runnable;
+
+        public Runner(final Runnable runnable) {
+            this.runnable = runnable;
+        }
+
+        public void run() {
+            boolean ok = false;
+            CTH.set(Dependency.this);
+            try {
+                runnable.run();
+                ok = true;
+            } finally {
+                CTH.set(null);
+                final List<Dependency> tasks;
+                synchronized (lock) {
+                    tasks = dependents;
+                    dependents = null;
+                    runnable = null;
+                    state = ok ? State.DONE : State.FAILED;
+                }
+                if (ok) {
+                    for (Dependency task : tasks) {
+                        task.dependencyFinished();
+                    }
+                } else {
+                    for (Dependency task : tasks) {
+                        task.dependencyFailed();
+                    }
+                }
+            }
+        }
+    }
+
+    private enum State {
+        /**
+         * Waiting for dependencies to be resolved.
+         */
+        WAITING,
+        /**
+         * Now running.
+         */
+        RUNNING,
+        /**
+         * Execution failed.
+         */
+        FAILED,
+        /**
+         * Execution completed.
+         */
+        DONE,
+    }
+
+    /**
+     * Get the dependency task which this thread is currently running.  This may be used to add dependencies on the currently
+     * running task.
+     *
+     * @return the currently running task, or {@code null} if the current thread is not running a dependency task
+     */
+    public static Dependency currentTask() {
+        return CTH.get();
+    }
+
+    private static final ThreadLocal<Dependency> CTH = new ThreadLocal<Dependency>();
+}

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DependencyTaskBuilder.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DependencyTaskBuilder.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/DependencyTaskBuilder.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Arrays;
+import java.util.concurrent.Executor;
+
+/**
+ * A builder for a dependency task.
+ */
+public final class DependencyTaskBuilder {
+    private final Collection<Dependency> dependencies = new LinkedHashSet<Dependency>();
+    private final Executor executor;
+    private final Runnable task;
+
+    DependencyTaskBuilder(final Executor executor, final Runnable task) {
+        this.executor = executor;
+        this.task = task;
+    }
+
+    /**
+     * Add a dependency.
+     *
+     * @param dependency the dependency
+     * @return this builder
+     */
+    public DependencyTaskBuilder add(Dependency dependency) {
+        if (dependency == null) {
+            throw new NullPointerException("dependency is null");
+        }
+        dependencies.add(dependency);
+        return this;
+    }
+
+    /**
+     * Add many dependencies.
+     *
+     * @param dependencies the dependencies
+     * @return this builder
+     */
+    public DependencyTaskBuilder add(Collection<Dependency> dependencies) {
+        this.dependencies.addAll(dependencies);
+        return this;
+    }
+
+    /**
+     * Add many dependencies.
+     *
+     * @param dependencies the dependencies
+     * @return this builder
+     */
+    public DependencyTaskBuilder add(Dependency... dependencies) {
+        this.dependencies.addAll(Arrays.asList(dependencies));
+        return this;
+    }
+
+    /**
+     * Create, and possibly execute, a dependent task from this builder.
+     *
+     * @return the new dependent task
+     */
+    public Dependency create() {
+        final Collection<Dependency> dependencies = this.dependencies;
+        final Dependency dependentTask = new Dependency(executor, task, dependencies.size() + 1);
+        for (Dependency dependency : dependencies) {
+            dependency.addDependent(dependentTask);
+        }
+        dependentTask.dependencyFinished();
+        return dependentTask;
+    }
+}

Modified: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/JBossExecutors.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -33,7 +33,6 @@
 import java.security.AccessController;
 import java.security.AccessControlContext;
 import java.security.Permission;
-import java.lang.reflect.Field;
 import org.jboss.logging.Logger;
 
 /**
@@ -55,9 +54,9 @@
         }
     });
 
-    private static final DirectExecutorService DIRECT_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(SimpleDirectExecutor.INSTANCE);
-    private static final DirectExecutorService REJECTING_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(RejectingExecutor.INSTANCE);
-    private static final DirectExecutorService DISCARDING_EXECUTOR_SERVICE = new ProtectedDirectExecutorService(DiscardingExecutor.INSTANCE);
+    private static final DirectExecutorService DIRECT_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(SimpleDirectExecutor.INSTANCE);
+    private static final DirectExecutorService REJECTING_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(RejectingExecutor.INSTANCE);
+    private static final DirectExecutorService DISCARDING_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(DiscardingExecutor.INSTANCE);
 
     // ==================================================
     // DIRECT EXECUTORS
@@ -386,7 +385,7 @@
      * @return the executor service
      */
     public static ExecutorService protectedExecutorService(final Executor target) {
-        return new ProtectedExecutorService(target);
+        return new DelegatingExecutorService(target);
     }
 
     /**
@@ -397,7 +396,7 @@
      * @return the executor service
      */
     public static DirectExecutorService protectedDirectExecutorService(final DirectExecutor target) {
-        return new ProtectedDirectExecutorService(target);
+        return new DelegatingDirectExecutorService(target);
     }
 
     /**
@@ -408,7 +407,7 @@
      * @return the executor service
      */
     public static ScheduledExecutorService protectedScheduledExecutorService(final ScheduledExecutorService target) {
-        return new ProtectedScheduledExecutorService(target);
+        return new DelegatingScheduledExecutorService(target);
     }
 
     // ==================================================
@@ -449,66 +448,12 @@
         }
     };
 
-    private static final Runnable THREAD_LOCAL_RESETTER = new ThreadLocalResetter();
-
-    private static final class ThreadLocalResetter implements Runnable {
-        private static final Field THREAD_LOCAL_MAP_FIELD;
-        private static final Field INHERITABLE_THREAD_LOCAL_MAP_FIELD;
-
-        static {
-            THREAD_LOCAL_MAP_FIELD = AccessController.doPrivileged(new PrivilegedAction<Field>() {
-                public Field run() {
-                    final Field field;
-                    try {
-                        field = Thread.class.getDeclaredField("threadLocals");
-                        field.setAccessible(true);
-                    } catch (NoSuchFieldException e) {
-                        return null;
-                    }
-                    return field;
-                }
-            });
-            INHERITABLE_THREAD_LOCAL_MAP_FIELD = AccessController.doPrivileged(new PrivilegedAction<Field>() {
-                public Field run() {
-                    final Field field;
-                    try {
-                        field = Thread.class.getDeclaredField("inheritableThreadLocals");
-                        field.setAccessible(true);
-                    } catch (NoSuchFieldException e) {
-                        return null;
-                    }
-                    return field;
-                }
-            });
-        }
-
-        private ThreadLocalResetter() {
-        }
-
-        public void run() {
-            final Thread thread = Thread.currentThread();
-            clear(thread, THREAD_LOCAL_MAP_FIELD);
-            clear(thread, INHERITABLE_THREAD_LOCAL_MAP_FIELD);
-        }
-
-        private static void clear(final Thread currentThread, final Field field) {
-            try {
-                if (field != null) field.set(currentThread, null);
-            } catch (IllegalAccessException e) {
-                // ignore
-            }
-        }
-
-        public String toString() {
-            return "Thread-local resetting Runnable";
-        }
-    }
-
     // ==================================================
     // RUNNABLES
     // ==================================================
 
     private static final Runnable NULL_RUNNABLE = new NullRunnable();
+    private static final Runnable THREAD_LOCAL_RESETTER = new ThreadLocalResetter();
 
     /**
      * Get the null runnable which does nothing.
@@ -683,4 +628,113 @@
     public static Thread.UncaughtExceptionHandler loggingExceptionHandler() {
         return LOGGING_HANDLER;
     }
+
+    private static <R extends Runnable> void logError(final R runnable, final Throwable t, final String method) {
+        THREAD_ERROR_LOGGER.errorf(t, "Notifier %s() method invocation failed for task %s", method, runnable);
+    }
+
+    private static <R extends Runnable, A> void started(TaskNotifier<? super R, ? super A> notifier, R runnable, A attachment) {
+        try {
+            notifier.started(runnable, attachment);
+        } catch (Throwable t) {
+            logError(runnable, t, "started");
+        }
+    }
+
+    private static <R extends Runnable, A> void finished(TaskNotifier<? super R, ? super A> notifier, R runnable, A attachment) {
+        try {
+            notifier.finished(runnable, attachment);
+        } catch (Throwable t) {
+            logError(runnable, t, "finished");
+        }
+    }
+
+    private static <R extends Runnable, A> void failed(TaskNotifier<? super R, ? super A> notifier, Throwable reason, R runnable, A attachment) {
+        try {
+            notifier.failed(runnable, reason, attachment);
+        } catch (Throwable t) {
+            logError(runnable, t, "failed");
+        }
+    }
+
+    /**
+     * Run a task through the given direct executor, invoking the given notifier with the given attachment.
+     *
+     * @param task the task
+     * @param directExecutor the executor
+     * @param notifier the notifier
+     * @param attachment the attachment
+     * @param <R> the task type
+     * @param <A> the attachment type
+     */
+    public static <R extends Runnable, A> void run(R task, DirectExecutor directExecutor, TaskNotifier<? super R, ? super A> notifier, A attachment) {
+        started(notifier, task, attachment);
+        boolean ok = false;
+        try {
+            directExecutor.execute(task);
+            ok = true;
+        } catch (RuntimeException t) {
+            failed(notifier, t, task, attachment);
+            throw t;
+        } catch (Error t) {
+            failed(notifier, t, task, attachment);
+            throw t;
+        } catch (Throwable t) {
+            failed(notifier, t, task, attachment);
+            throw new RuntimeException("Unknown throwable received", t);
+        } finally {
+            if (ok) finished(notifier, task, attachment);
+        }
+    }
+
+    /**
+     * Run a task, invoking the given notifier with the given attachment.
+     *
+     * @param task the task
+     * @param notifier the notifier
+     * @param attachment the attachment
+     * @param <R> the task type
+     * @param <A> the attachment type
+     */
+    public static <R extends Runnable, A> void run(R task, TaskNotifier<? super R, ? super A> notifier, A attachment) {
+        run(task, directExecutor(), notifier, attachment);
+    }
+
+    /**
+     * Get a notifying runnable wrapper for a task.  The notifier will be invoked when the task is run.
+     *
+     * @param task the task
+     * @param notifier the notifier
+     * @param attachment the attachment
+     * @param <R> the task type
+     * @param <A> the attachment type
+     * @return the wrapping runnable
+     */
+    public static <R extends Runnable, A> Runnable notifyingRunnable(R task, TaskNotifier<? super R, ? super A> notifier, A attachment) {
+        return new NotifyingRunnable<R, A>(task, notifier, attachment);
+    }
+
+    /**
+     * Get a notifying direct executor.  The notifier will be invoked when each task is run.
+     *
+     * @param delegate the executor which will actually run the task
+     * @param notifier the notifier
+     * @param attachment the attachment
+     * @param <A> the attachment type
+     * @return the direct executor
+     */
+    public static <A> DirectExecutor notifyingDirectExecutor(DirectExecutor delegate, TaskNotifier<Runnable, ? super A> notifier, A attachment) {
+        return new NotifyingDirectExecutor<A>(delegate, notifier, attachment);
+    }
+
+    /**
+     * Create a builder for a dependent task.
+     *
+     * @param executor the executor to use
+     * @param task the task to run when all dependencies are met
+     * @return the builder
+     */
+    public static DependencyTaskBuilder dependencyTaskBuilder(final Executor executor, final Runnable task) {
+        return new DependencyTaskBuilder(executor, task);
+    }
 }

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingDirectExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingDirectExecutor.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingDirectExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+final class NotifyingDirectExecutor<A> extends DelegatingDirectExecutor implements DirectExecutor {
+
+    private final TaskNotifier<Runnable, ? super A> notifier;
+    private final A attachment;
+
+    NotifyingDirectExecutor(final DirectExecutor delegate, final TaskNotifier<Runnable, ? super A> notifier, final A attachment) {
+        super(delegate);
+        this.notifier = notifier;
+        this.attachment = attachment;
+    }
+
+    public void execute(final Runnable command) {
+        JBossExecutors.run(command, getDelegate(), notifier, attachment);
+    }
+}

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingRunnable.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingRunnable.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/NotifyingRunnable.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+class NotifyingRunnable<R extends Runnable, A> extends DelegatingRunnable implements Runnable {
+
+    private final TaskNotifier<? super R, ? super A> notifier;
+    private final A attachment;
+
+    NotifyingRunnable(final R delegate, final TaskNotifier<? super R, ? super A> notifier, final A attachment) {
+        super(delegate);
+        this.notifier = notifier;
+        this.attachment = attachment;
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    protected R getDelegate() {
+        return (R) super.getDelegate();
+    }
+
+    public void run() {
+        JBossExecutors.run(getDelegate(), notifier, attachment);
+    }
+}

Deleted: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -1,34 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.threads;
-
-/**
- * A direct executor that simply delegates to another direct executor.  Use instances of this class to hide extra methods on
- * another executor.
- */
-public class ProtectedDirectExecutor extends ProtectedExecutor implements DirectExecutor {
-
-    public ProtectedDirectExecutor(final DirectExecutor delegate) {
-        super(delegate);
-    }
-}

Deleted: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedDirectExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -1,32 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.threads;
-
-/**
- * A {@code DirectExecutor} version of {@code ProtectedExecutorService}.
- */
-public class ProtectedDirectExecutorService extends ProtectedExecutorService implements DirectExecutorService {
-    public ProtectedDirectExecutorService(final DirectExecutor delegate) {
-        super(delegate);
-    }
-}

Deleted: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutor.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -1,50 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.threads;
-
-import java.util.concurrent.Executor;
-
-/**
- * An executor that simply delegates to another executor.  Use instances of this class to hide extra methods on
- * another executor.
- */
-public class ProtectedExecutor implements Executor {
-    private final Executor delegate;
-
-    public ProtectedExecutor(final Executor delegate) {
-        this.delegate = delegate;
-    }
-
-    /**
-     * Execute a task by passing it to the delegate executor.
-     *
-     * @param command the task
-     */
-    public void execute(final Runnable command) {
-        delegate.execute(command);
-    }
-
-    public String toString() {
-        return String.format("%s -> %s", super.toString(), delegate);
-    }
-}

Deleted: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -1,75 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.threads;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.AbstractExecutorService;
-import java.util.concurrent.Executor;
-import java.util.List;
-
-/**
- * An implementation of {@code ExecutorService} that delegates to the real executor, while disallowing termination.
- */
-public class ProtectedExecutorService extends AbstractExecutorService implements ExecutorService {
-    private final Executor delegate;
-
-    public ProtectedExecutorService(final Executor delegate) {
-        this.delegate = delegate;
-    }
-
-    public void execute(final Runnable command) {
-        delegate.execute(command);
-    }
-
-    public boolean isShutdown() {
-        // container managed executors are never shut down from the application's perspective
-        return false;
-    }
-
-    public boolean isTerminated() {
-        // container managed executors are never shut down from the application's perspective
-        return false;
-    }
-
-    public boolean awaitTermination(final long timeout, final TimeUnit unit) throws InterruptedException {
-        unit.sleep(timeout);
-        return false;
-    }
-
-    public void shutdown() {
-        throw new SecurityException("shutdown() not allowed on container-managed executor");
-    }
-
-    public List<Runnable> shutdownNow() {
-        throw new SecurityException("shutdownNow() not allowed on container-managed executor");
-    }
-
-    public static ExecutorService directExecutorService() {
-        return new ProtectedExecutorService(JBossExecutors.directExecutor());
-    }
-
-    public String toString() {
-        return String.format("%s -> %s", super.toString(), delegate);
-    }
-}

Deleted: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedScheduledExecutorService.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedScheduledExecutorService.java	2009-08-06 04:30:52 UTC (rev 92049)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ProtectedScheduledExecutorService.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -1,56 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.threads;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.Callable;
-
-/**
- * An implementation of {@code ScheduledExecutorService} that delegates to the real executor, while disallowing termination.
- */
-public class ProtectedScheduledExecutorService extends ProtectedExecutorService implements ScheduledExecutorService {
-    private final ScheduledExecutorService delegate;
-
-    public ProtectedScheduledExecutorService(final ScheduledExecutorService delegate) {
-        super(delegate);
-        this.delegate = delegate;
-    }
-
-    public ScheduledFuture<?> schedule(final Runnable command, final long delay, final TimeUnit unit) {
-        return delegate.schedule(command, delay, unit);
-    }
-
-    public <V> ScheduledFuture<V> schedule(final Callable<V> callable, final long delay, final TimeUnit unit) {
-        return delegate.schedule(callable, delay, unit);
-    }
-
-    public ScheduledFuture<?> scheduleAtFixedRate(final Runnable command, final long initialDelay, final long period, final TimeUnit unit) {
-        return delegate.scheduleAtFixedRate(command, initialDelay, period, unit);
-    }
-
-    public ScheduledFuture<?> scheduleWithFixedDelay(final Runnable command, final long initialDelay, final long delay, final TimeUnit unit) {
-        return delegate.scheduleWithFixedDelay(command, initialDelay, delay, unit);
-    }
-}
\ No newline at end of file

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/TaskNotifier.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/TaskNotifier.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/TaskNotifier.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+/**
+ * A notifier which is called when tasks start, stop, or fail.
+ *
+ * @param <R> the task type
+ * @param <A> the attachment type
+ */
+public interface TaskNotifier<R extends Runnable, A> {
+
+    /**
+     * A task was started.
+     *
+     * @param runnable the task
+     * @param attachment the attachment
+     */
+    void started(R runnable, A attachment);
+
+    /**
+     * A task has failed.
+     *
+     * @param runnable the task
+     * @param reason the reason for the failure
+     * @param attachment the attachment
+     */
+    void failed(R runnable, Throwable reason, A attachment);
+
+    /**
+     * A task has completed.
+     *
+     * @param runnable the task
+     * @param attachment the attachment
+     */
+    void finished(R runnable, A attachment);
+}

Added: projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadLocalResetter.java
===================================================================
--- projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadLocalResetter.java	                        (rev 0)
+++ projects/jboss-threads/trunk/main/src/main/java/org/jboss/threads/ThreadLocalResetter.java	2009-08-06 05:00:35 UTC (rev 92050)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.threads;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+final class ThreadLocalResetter implements Runnable {
+    private static final Field THREAD_LOCAL_MAP_FIELD;
+    private static final Field INHERITABLE_THREAD_LOCAL_MAP_FIELD;
+
+    static {
+        THREAD_LOCAL_MAP_FIELD = AccessController.doPrivileged(new PrivilegedAction<Field>() {
+            public Field run() {
+                final Field field;
+                try {
+                    field = Thread.class.getDeclaredField("threadLocals");
+                    field.setAccessible(true);
+                } catch (NoSuchFieldException e) {
+                    return null;
+                }
+                return field;
+            }
+        });
+        INHERITABLE_THREAD_LOCAL_MAP_FIELD = AccessController.doPrivileged(new PrivilegedAction<Field>() {
+            public Field run() {
+                final Field field;
+                try {
+                    field = Thread.class.getDeclaredField("inheritableThreadLocals");
+                    field.setAccessible(true);
+                } catch (NoSuchFieldException e) {
+                    return null;
+                }
+                return field;
+            }
+        });
+    }
+
+    ThreadLocalResetter() {
+    }
+
+    public void run() {
+        final Thread thread = Thread.currentThread();
+        clear(thread, THREAD_LOCAL_MAP_FIELD);
+        clear(thread, INHERITABLE_THREAD_LOCAL_MAP_FIELD);
+    }
+
+    private static void clear(final Thread currentThread, final Field field) {
+        try {
+            if (field != null) field.set(currentThread, null);
+        } catch (IllegalAccessException e) {
+            // ignore
+        }
+    }
+
+    public String toString() {
+        return "Thread-local resetting Runnable";
+    }
+}




More information about the jboss-cvs-commits mailing list