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
016package org.granite.gravity.generic;
017
018import org.granite.logging.Logger;
019
020
021/* Extract from Jetty 6.1 to support other servlet containers */
022public 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}