/*
* Created on Dec 11, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library 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 library 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
* library; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jactr.core.concurrent;
import java.util.List;
import java.util.WeakHashMap;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/**
* An executor that can be wrapped around others and will check to be sure that
* any execute calls are not made from a thread that is managed by this executor
* service. this can prevent a fairly nasty and stupid deadlock occurence.
* <code>
* SafeExecutorService ses = new SafeExecutorService(false);
SafeExecutorThreadFactory setf = new SafeExecutorThreadFactory(ses, Executors.defaultThreadFactory());
ses.setDelegate(Executors.newSingleThreadExecutor(setf));
</code>
*
* @author developer
*/
public class SafeExecutorService extends AbstractExecutorService
{
private ExecutorService _delegate;
final private boolean _permitSelfExecution;
final private WeakHashMap<Thread, Thread> _managedThreads = new WeakHashMap<Thread, Thread>();
public SafeExecutorService(boolean permitSelfExecutions)
{
this(null, permitSelfExecutions);
}
/**
*
*/
public SafeExecutorService(ExecutorService delegate,
boolean permitSelfExecutions)
{
_delegate = delegate;
_permitSelfExecution = permitSelfExecutions;
}
public void setDelegate(ExecutorService service)
{
_delegate = service;
}
public ExecutorService getDelegate()
{
return _delegate;
}
public boolean allowsSelfExecutions()
{
return _permitSelfExecution;
}
/**
* @see java.util.concurrent.ExecutorService#awaitTermination(long,
* java.util.concurrent.TimeUnit)
*/
public boolean awaitTermination(long arg0, TimeUnit arg1)
throws InterruptedException
{
return _delegate.awaitTermination(arg0, arg1);
}
/**
* @see java.util.concurrent.ExecutorService#isShutdown()
*/
public boolean isShutdown()
{
return _delegate.isShutdown();
}
/**
* @see java.util.concurrent.ExecutorService#isTerminated()
*/
public boolean isTerminated()
{
return _delegate.isTerminated();
}
/**
* @see java.util.concurrent.ExecutorService#shutdown()
*/
public void shutdown()
{
_delegate.shutdown();
}
/**
* @see java.util.concurrent.ExecutorService#shutdownNow()
*/
public List<Runnable> shutdownNow()
{
return _delegate.shutdownNow();
}
/**
* @see java.util.concurrent.Executor#execute(java.lang.Runnable)
*/
public void execute(Runnable arg0)
{
canExecute(arg0);
_delegate.execute(arg0);
}
public void addManagedThread(Thread thread)
{
_managedThreads.put(thread, thread);
}
public void removeManagedThread(Thread thread)
{
_managedThreads.remove(thread);
}
public boolean isManagedThread(Thread thread)
{
return _managedThreads.containsKey(thread);
}
/**
* test to see if the current thread is managed and we permit self executions
*/
protected void canExecute(Runnable arg0)
{
if (!allowsSelfExecutions() && isManagedThread(Thread.currentThread()))
throw new IllegalStateException(
"SafeExecutorService does not permit executing events from a managed thread, cannot execute "
+ arg0);
}
}