org/objectweb/proactive/core/exceptions/manager/ExceptionMaskStack.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.core.exceptions.manager;
00032 
00033 import java.util.Collection;
00034 import java.util.Iterator;
00035 import java.util.LinkedList;
00036 import java.util.NoSuchElementException;
00037 
00038 
00039 public class ExceptionMaskStack {
00040 
00041     /* List of ExceptionMaskLevel, starts with the top */
00042     private LinkedList<ExceptionMaskLevel> stack;
00043 
00044     /* The combination of all masks */
00045     private ExceptionMaskLevel currentExceptionMask;
00046 
00047     private ExceptionMaskStack() {
00048         stack = new LinkedList<ExceptionMaskLevel>();
00049         currentExceptionMask = new ExceptionMaskLevel();
00050     }
00051 
00052     /*
00053      * As there is one call stack per thread, there is also one exception
00054      * stack per thread. So we use the threadlocal stuff which may be an
00055      * optimized way of doing this thread local thing
00056      */
00057     private static ThreadLocal threadLocalMask = new ThreadLocal() {
00058             protected synchronized Object initialValue() {
00059                 return new ExceptionMaskStack();
00060             }
00061         };
00062 
00063     /* The mask for the current thread */
00064     static ExceptionMaskStack get() {
00065         return (ExceptionMaskStack) threadLocalMask.get();
00066     }
00067 
00068     void push(Class[] exceptions) {
00069         ExceptionMaskLevel level = new ExceptionMaskLevel(this, exceptions);
00070         stack.add(0, level);
00071         currentExceptionMask.addExceptionTypes(level);
00072     }
00073 
00074     void pop() {
00075         if (stack.isEmpty()) {
00076             throw new IllegalStateException("The stack has nothing to pop");
00077         }
00078 
00079         stack.removeFirst();
00080         updateExceptionMask();
00081     }
00082 
00083     /* Recompute the full mask */
00084     private void updateExceptionMask() {
00085         currentExceptionMask = new ExceptionMaskLevel();
00086         Iterator<ExceptionMaskLevel> iter = stack.iterator();
00087         while (iter.hasNext()) {
00088             ExceptionMaskLevel level = iter.next();
00089             currentExceptionMask.addExceptionTypes(level);
00090         }
00091     }
00092 
00093     void throwArrivedException() {
00094         Collection caughtExceptions = getTopLevel().getCaughtExceptions();
00095         synchronized (caughtExceptions) {
00096             if (!caughtExceptions.isEmpty()) {
00097                 Throwable exc = (Throwable) caughtExceptions.iterator().next();
00098                 ExceptionThrower.throwException(exc);
00099             }
00100         }
00101     }
00102 
00103     private ExceptionMaskLevel getTopLevel() {
00104         try {
00105             return stack.getFirst();
00106         } catch (NoSuchElementException nsee) {
00107             throw new IllegalStateException("Exception stack is empty");
00108         }
00109     }
00110 
00111     void waitForPotentialException(boolean allLevels) {
00112         if (allLevels) {
00113             Iterator<ExceptionMaskLevel> iter = stack.iterator();
00114             while (iter.hasNext()) {
00115                 ExceptionMaskLevel level = iter.next();
00116                 level.waitForPotentialException();
00117             }
00118         } else {
00119             getTopLevel().waitForPotentialException();
00120         }
00121     }
00122 
00123     /* Optimization: we don't always insert at the top level */
00124     ExceptionMaskLevel findBestLevel(Class[] c) {
00125         Iterator<ExceptionMaskLevel> iter = stack.iterator();
00126         while (iter.hasNext()) {
00127             ExceptionMaskLevel level = iter.next();
00128             if (level.catchRuntimeException() ||
00129                     level.areExceptionTypesCaught(c)) {
00130                 return level;
00131             }
00132         }
00133 
00134         throw new IllegalStateException("No exception level found");
00135     }
00136 
00137     void waitForIntersection(Class[] exceptions) {
00138         if (currentExceptionMask.areExceptionTypesCaught(exceptions)) {
00139             Iterator<ExceptionMaskLevel> iter = stack.iterator();
00140             while (iter.hasNext()) {
00141                 ExceptionMaskLevel level = iter.next();
00142                 if (level.areExceptionTypesCaught(exceptions)) {
00143                     level.waitForPotentialException();
00144                 }
00145             }
00146         }
00147     }
00148 
00149     boolean areExceptionTypesCaught(Class[] c) {
00150         return currentExceptionMask.areExceptionTypesCaught(c);
00151     }
00152 
00153     boolean isExceptionTypeCaught(Class c) {
00154         return currentExceptionMask.isExceptionTypeCaught(c);
00155     }
00156 
00157     boolean isRuntimeExceptionHandled() {
00158         return currentExceptionMask.catchRuntimeException();
00159     }
00160 
00161     Collection getAllExceptions() {
00162         return getTopLevel().getAllExceptions();
00163     }
00164 }

Generated on Mon Jan 22 15:16:07 2007 for ProActive by  doxygen 1.5.1