001    //========================================================================
002    //$Id: WaitingContinuation.java,v 1.1 2005/11/14 17:45:56 gregwilkins Exp $
003    //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
004    //------------------------------------------------------------------------
005    //Licensed under the Apache License, Version 2.0 (the "License");
006    //you may not use this file except in compliance with the License.
007    //You may obtain a copy of the License at 
008    //http://www.apache.org/licenses/LICENSE-2.0
009    //Unless required by applicable law or agreed to in writing, software
010    //distributed under the License is distributed on an "AS IS" BASIS,
011    //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    //See the License for the specific language governing permissions and
013    //limitations under the License.
014    //========================================================================
015    
016    package org.granite.gravity.generic;
017    
018    import org.granite.logging.Logger;
019    
020    
021    /* Extract from Jetty 6.1 to support other servlet containers */
022    public class WaitingContinuation {
023            
024            private static final Logger log = Logger.getLogger(WaitingContinuation.class);
025            
026        Object _mutex;
027        Object _object;
028        boolean _new=true;
029        boolean _resumed=false;
030        boolean _pending=false;
031        boolean _expired=false;
032    
033        public WaitingContinuation()
034        {
035            _mutex=this;
036        }
037        
038        public WaitingContinuation(Object mutex)
039        {
040            _mutex=mutex==null?this:mutex;
041        }
042        
043        public void resume()
044        {
045            synchronized (_mutex)
046            {
047                _resumed=true;
048                _mutex.notify();
049            }
050        }
051        
052        public void reset()
053        {
054            synchronized (_mutex)
055            {
056                _resumed=false;
057                _pending=false;
058                _expired=false;
059                _mutex.notify();
060            }
061        }
062    
063        public boolean isNew()
064        {
065            return _new;
066        }
067    
068        public boolean suspend(long timeout)
069        {
070            synchronized (_mutex)
071            {
072                _new=false;
073                _pending=true;
074                boolean result;
075                try
076                {
077                    log.debug("Continuation suspend " + timeout);
078                    if (!_resumed && timeout>=0)
079                    {
080                        if (timeout==0)
081                            _mutex.wait();
082                        else if (timeout>0)
083                            _mutex.wait(timeout);
084                            
085                    }
086                }
087                catch (InterruptedException e)
088                {
089                    _expired=true;
090                    log.debug("Continuation timeout");
091                }
092                finally
093                {
094                    result=_resumed;
095                    _resumed=false;
096                    _pending=false;
097                }
098                
099                return result;
100            }
101        }
102        
103        public boolean isPending()
104        {
105            synchronized (_mutex)
106            {
107                return _pending;
108            }
109        }
110        
111        public boolean isResumed()
112        {
113            synchronized (_mutex)
114            {
115                return _resumed;
116            }
117        }
118        
119        public boolean isExpired()
120        {
121            synchronized (_mutex)
122            {
123                return _expired;
124            }
125        }
126    
127        public Object getObject()
128        {
129            return _object;
130        }
131    
132        public void setObject(Object object)
133        {
134            _object = object;
135        }
136    
137        public Object getMutex()
138        {
139            return _mutex;
140        }
141    
142        public void setMutex(Object mutex)
143        {
144            if (!_new && _mutex!=this && _pending)
145                throw new IllegalStateException();
146            _mutex = mutex==null ? this : mutex; 
147        }
148    
149        @Override
150        public String toString()
151        {
152            synchronized (this)
153            {
154                return "WaitingContinuation@"+hashCode()+
155                (_new?",new":"")+
156                (_pending?",pending":"")+
157                (_resumed?",resumed":"")+
158                (_expired?",expired":"");
159            }
160        }
161    }