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
037package org.granite.gravity.generic;
038
039import org.granite.logging.Logger;
040
041
042/* Extract from Jetty 6.1 to support other servlet containers */
043public 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}