Index: main/java/com/sun/grizzly/util/DefaultThreadPool.java =================================================================== --- main/java/com/sun/grizzly/util/DefaultThreadPool.java (revision 3293) +++ main/java/com/sun/grizzly/util/DefaultThreadPool.java (working copy) @@ -343,6 +343,16 @@ sb.append(", is-shutdown=").append(isShutdown()); } + @Override + protected void beforeExecute(Thread t, Runnable r) { + ((WorkerThreadImpl) t).createByteBuffer(false); + } + + @Override + protected void afterExecute(Runnable r, Throwable t) { + ((WorkerThreadImpl) Thread.currentThread()).reset(); + } + private class DefaultWorkerThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread thread = new WorkerThreadImpl(DefaultThreadPool.this, Index: main/java/com/sun/grizzly/util/FixedThreadPool.java =================================================================== --- main/java/com/sun/grizzly/util/FixedThreadPool.java (revision 3293) +++ main/java/com/sun/grizzly/util/FixedThreadPool.java (working copy) @@ -309,7 +309,46 @@ return threadFactory; } - + /** + * Method invoked prior to executing the given Runnable in the + * given thread. This method is invoked by thread t that + * will execute task r, and may be used to re-initialize + * ThreadLocals, or to perform logging. + * + *

This implementation does nothing, but may be customized in + * subclasses. Note: To properly nest multiple overridings, subclasses + * should generally invoke super.beforeExecute at the end of + * this method. + * + * @param t the thread that will run task r. + * @param r the task that will be executed. + */ + protected void beforeExecute(Thread t, Runnable r) { } + + /** + * Method invoked upon completion of execution of the given Runnable. + * This method is invoked by the thread that executed the task. If + * non-null, the Throwable is the uncaught RuntimeException + * or Error that caused execution to terminate abruptly. + * + *

Note: When actions are enclosed in tasks (such as + * {@link java.util.concurrent.FutureTask}) either explicitly or via methods such as + * submit, these task objects catch and maintain + * computational exceptions, and so they do not cause abrupt + * termination, and the internal exceptions are not + * passed to this method. + * + *

This implementation does nothing, but may be customized in + * subclasses. Note: To properly nest multiple overridings, subclasses + * should generally invoke super.afterExecute at the + * beginning of this method. + * + * @param r the runnable that has completed. + * @param t the exception that caused termination, or null if + * execution completed normally. + */ + protected void afterExecute(Runnable r, Throwable t) { } + protected class BasicWorker implements Runnable{ Thread t; @@ -333,10 +372,15 @@ if (r == poison || r == null){ return; } + boolean ran = false; + beforeExecute( t, r ); try { approximateRunningWorkerCount.incrementAndGet(); r.run(); + afterExecute( r, null ); } catch( Throwable t ) { + if (!ran) + afterExecute( r, t ); throw t; } finally { approximateRunningWorkerCount.decrementAndGet();