001    /**
002     *   GRANITE DATA SERVICES
003     *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004     *
005     *   This file is part of the Granite Data Services Platform.
006     *
007     *   Granite Data Services is free software; you can redistribute it and/or
008     *   modify it under the terms of the GNU Lesser General Public
009     *   License as published by the Free Software Foundation; either
010     *   version 2.1 of the License, or (at your option) any later version.
011     *
012     *   Granite Data Services is distributed in the hope that it will be useful,
013     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015     *   General Public License for more details.
016     *
017     *   You should have received a copy of the GNU Lesser General Public
018     *   License along with this library; if not, write to the Free Software
019     *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020     *   USA, or see <http://www.gnu.org/licenses/>.
021     */
022    //========================================================================
023    //$Id: WaitingContinuation.java,v 1.1 2005/11/14 17:45:56 gregwilkins Exp $
024    //Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
025    //------------------------------------------------------------------------
026    //Licensed under the Apache License, Version 2.0 (the "License");
027    //you may not use this file except in compliance with the License.
028    //You may obtain a copy of the License at 
029    //http://www.apache.org/licenses/LICENSE-2.0
030    //Unless required by applicable law or agreed to in writing, software
031    //distributed under the License is distributed on an "AS IS" BASIS,
032    //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
033    //See the License for the specific language governing permissions and
034    //limitations under the License.
035    //========================================================================
036    
037    package org.granite.gravity.generic;
038    
039    import org.granite.logging.Logger;
040    
041    
042    /* Extract from Jetty 6.1 to support other servlet containers */
043    public class WaitingContinuation {
044            
045            private static final Logger log = Logger.getLogger(WaitingContinuation.class);
046            
047        Object _mutex;
048        Object _object;
049        boolean _new=true;
050        boolean _resumed=false;
051        boolean _pending=false;
052        boolean _expired=false;
053    
054        public WaitingContinuation()
055        {
056            _mutex=this;
057        }
058        
059        public WaitingContinuation(Object mutex)
060        {
061            _mutex=mutex==null?this:mutex;
062        }
063        
064        public void resume()
065        {
066            synchronized (_mutex)
067            {
068                _resumed=true;
069                _mutex.notify();
070            }
071        }
072        
073        public void reset()
074        {
075            synchronized (_mutex)
076            {
077                _resumed=false;
078                _pending=false;
079                _expired=false;
080                _mutex.notify();
081            }
082        }
083    
084        public boolean isNew()
085        {
086            return _new;
087        }
088    
089        public boolean suspend(long timeout)
090        {
091            synchronized (_mutex)
092            {
093                _new=false;
094                _pending=true;
095                boolean result;
096                try
097                {
098                    log.debug("Continuation suspend " + timeout);
099                    if (!_resumed && timeout>=0)
100                    {
101                        if (timeout==0)
102                            _mutex.wait();
103                        else if (timeout>0)
104                            _mutex.wait(timeout);
105                            
106                    }
107                }
108                catch (InterruptedException e)
109                {
110                    _expired=true;
111                    log.debug("Continuation timeout");
112                }
113                finally
114                {
115                    result=_resumed;
116                    _resumed=false;
117                    _pending=false;
118                }
119                
120                return result;
121            }
122        }
123        
124        public boolean isPending()
125        {
126            synchronized (_mutex)
127            {
128                return _pending;
129            }
130        }
131        
132        public boolean isResumed()
133        {
134            synchronized (_mutex)
135            {
136                return _resumed;
137            }
138        }
139        
140        public boolean isExpired()
141        {
142            synchronized (_mutex)
143            {
144                return _expired;
145            }
146        }
147    
148        public Object getObject()
149        {
150            return _object;
151        }
152    
153        public void setObject(Object object)
154        {
155            _object = object;
156        }
157    
158        public Object getMutex()
159        {
160            return _mutex;
161        }
162    
163        public void setMutex(Object mutex)
164        {
165            if (!_new && _mutex!=this && _pending)
166                throw new IllegalStateException();
167            _mutex = mutex==null ? this : mutex; 
168        }
169    
170        @Override
171        public String toString()
172        {
173            synchronized (this)
174            {
175                return "WaitingContinuation@"+hashCode()+
176                (_new?",new":"")+
177                (_pending?",pending":"")+
178                (_resumed?",resumed":"")+
179                (_expired?",expired":"");
180            }
181        }
182    }