How about this for an ExecutionContextManager?
public interface ExecutionContextManager {
void begin(Reaper r);
void checkPermission(Permission p) throws AccessControlException;
void end();
}
public interface Reaper extends Runnable {
void put(Thread t);
}
To be used like this:
ecm.begin(reaper);
try{
ecm.checkPermission(p);
ecm.checkPermission(m);
// do something, then return
return;
}finally {
ecm.end();
}
Two separate things are being managed here, the begin(reaper) method
associates the current Thread with it's AccessControlContext and Reaper,
and places it into the current execution cache, while end() removes it.
The checkPermission(p) method, checks the cache to see if the current
AccessControlContext has been tested with the given permission, if so it
returns, if not it checks the Permission, if it succeeds, it places it
into the checked cache. The Permission is then associated with the
current thread in the execution cache.
The end() method, removes the current Thread, AccessControlContext and
Reaper from the current execution cache.
When a revocation event occurs, a lock is held to prevent any
begin(reaper) method's from proceeding. The end() method in the finally
block stops any currently executing code blocks from returning during
the revocation event. Next the Permission's Class files are checked
against the Permission's currently in the execution cache. Any with the
matching Permission class files will require the
AccessContorlContext.checkPermission(Permission perm) call be made
again, any that fail will be added to a new collection pending reaping
and removed from the checked cache. The RevokeableDynamicPolicy is
capable of changing the AccessControlContext result, since it is called
by each ProtectionDomain in the AccessControlContext.
Each Reaper will be given a copy of it's Thread of execution, it doesn't
have to use it, but it's there if the Reaper wants to just interrupt the
thread to stop the block's execution. The Reapers will be placed on a
queue and run.
The locks are released once the reapers have completed.
When exit() is called by the finally block, the thread and
AccessControlContext's are removed from the current execution cache,
regardless of any revocation event.
It is also possible for the ExectionContextManager to have static class
methods like AccessController.
What are your thoughts?
Peter.