Merge pull request #4068 from eclipse/jetty-10.0.x-4058-autolock

Fixes #4058 - Review Locker.
This commit is contained in:
Simone Bordet 2019-09-11 23:56:52 +02:00 committed by GitHub
commit d91ee54627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 217 additions and 319 deletions

View File

@ -36,7 +36,7 @@ import java.util.concurrent.locks.Condition;
import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Scheduler;
/** /**
@ -68,24 +68,13 @@ public class ByteArrayEndPoint extends AbstractEndPoint
private static final ByteBuffer EOF = BufferUtil.allocate(0); private static final ByteBuffer EOF = BufferUtil.allocate(0);
private final Runnable _runFillable = new Runnable() private final Runnable _runFillable = () -> getFillInterest().fillable();
{ private final AutoLock _lock = new AutoLock();
@Override private final Condition _hasOutput = _lock.newCondition();
public void run()
{
getFillInterest().fillable();
}
};
private final Locker _locker = new Locker();
private final Condition _hasOutput = _locker.newCondition();
private final Queue<ByteBuffer> _inQ = new ArrayDeque<>(); private final Queue<ByteBuffer> _inQ = new ArrayDeque<>();
private ByteBuffer _out; private ByteBuffer _out;
private boolean _growOutput; private boolean _growOutput;
/**
*
*/
public ByteArrayEndPoint() public ByteArrayEndPoint()
{ {
this(null, 0, null, null); this(null, 0, null, null);
@ -138,7 +127,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public void doShutdownOutput() public void doShutdownOutput()
{ {
super.doShutdownOutput(); super.doShutdownOutput();
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_hasOutput.signalAll(); _hasOutput.signalAll();
} }
@ -148,7 +137,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public void doClose() public void doClose()
{ {
super.doClose(); super.doClose();
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_hasOutput.signalAll(); _hasOutput.signalAll();
} }
@ -180,7 +169,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
@Override @Override
protected void needsFillInterest() throws IOException protected void needsFillInterest() throws IOException
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (!isOpen()) if (!isOpen())
throw new ClosedChannelException(); throw new ClosedChannelException();
@ -205,7 +194,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public void addInput(ByteBuffer in) public void addInput(ByteBuffer in)
{ {
boolean fillable = false; boolean fillable = false;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (isEOF(_inQ.peek())) if (isEOF(_inQ.peek()))
throw new RuntimeIOException(new EOFException()); throw new RuntimeIOException(new EOFException());
@ -238,7 +227,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public void addInputAndExecute(ByteBuffer in) public void addInputAndExecute(ByteBuffer in)
{ {
boolean fillable = false; boolean fillable = false;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (isEOF(_inQ.peek())) if (isEOF(_inQ.peek()))
throw new RuntimeIOException(new EOFException()); throw new RuntimeIOException(new EOFException());
@ -263,7 +252,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
*/ */
public ByteBuffer getOutput() public ByteBuffer getOutput()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _out; return _out;
} }
@ -293,7 +282,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
{ {
ByteBuffer b; ByteBuffer b;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
b = _out; b = _out;
_out = BufferUtil.allocate(b.capacity()); _out = BufferUtil.allocate(b.capacity());
@ -314,7 +303,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
{ {
ByteBuffer b; ByteBuffer b;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
while (BufferUtil.isEmpty(_out) && !isOutputShutdown()) while (BufferUtil.isEmpty(_out) && !isOutputShutdown())
{ {
@ -351,7 +340,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
*/ */
public void setOutput(ByteBuffer out) public void setOutput(ByteBuffer out)
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_out = out; _out = out;
} }
@ -359,7 +348,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
} }
/** /**
* @return <code>true</code> if there are bytes remaining to be read from the encoded input * @return {@code true} if there are bytes remaining to be read from the encoded input
*/ */
public boolean hasMore() public boolean hasMore()
{ {
@ -373,7 +362,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public int fill(ByteBuffer buffer) throws IOException public int fill(ByteBuffer buffer) throws IOException
{ {
int filled = 0; int filled = 0;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
while (true) while (true)
{ {
@ -418,7 +407,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
public boolean flush(ByteBuffer... buffers) throws IOException public boolean flush(ByteBuffer... buffers) throws IOException
{ {
boolean flushed = true; boolean flushed = true;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (!isOpen()) if (!isOpen())
throw new IOException("CLOSED"); throw new IOException("CLOSED");
@ -467,7 +456,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
@Override @Override
public void reset() public void reset()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_inQ.clear(); _inQ.clear();
_hasOutput.signalAll(); _hasOutput.signalAll();
@ -507,7 +496,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
int q; int q;
ByteBuffer b; ByteBuffer b;
String o; String o;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
q = _inQ.size(); q = _inQ.size();
b = _inQ.peek(); b = _inQ.peek();

View File

@ -52,7 +52,7 @@ import org.eclipse.jetty.util.component.Graceful;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.ThreadPoolBudget; import org.eclipse.jetty.util.thread.ThreadPoolBudget;
@ -144,8 +144,8 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{ {
protected static final Logger LOG = Log.getLogger(AbstractConnector.class); protected static final Logger LOG = Log.getLogger(AbstractConnector.class);
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private final Condition _setAccepting = _locker.newCondition(); private final Condition _setAccepting = _lock.newCondition();
private final Map<String, ConnectionFactory> _factories = new LinkedHashMap<>(); // Order is important on server side, so we use a LinkedHashMap private final Map<String, ConnectionFactory> _factories = new LinkedHashMap<>(); // Order is important on server side, so we use a LinkedHashMap
private final Server _server; private final Server _server;
private final Executor _executor; private final Executor _executor;
@ -231,7 +231,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
* Get the {@link HttpChannel.Listener}s added to the connector * Get the {@link HttpChannel.Listener}s added to the connector
* as a single combined Listener. * as a single combined Listener.
* This is equivalent to a listener that iterates over the individual * This is equivalent to a listener that iterates over the individual
* listeners returned from <code>getBeans(HttpChannel.Listener.class);</code>, * listeners returned from {@code getBeans(HttpChannel.Listener.class);},
* except that: <ul> * except that: <ul>
* <li>The result is precomputed, so it is more efficient</li> * <li>The result is precomputed, so it is more efficient</li>
* <li>The result is ordered by the order added.</li> * <li>The result is ordered by the order added.</li>
@ -332,7 +332,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
protected void interruptAcceptors() protected void interruptAcceptors()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
for (Thread thread : _acceptors) for (Thread thread : _acceptors)
{ {
@ -387,7 +387,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
public void join(long timeout) throws InterruptedException public void join(long timeout) throws InterruptedException
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
for (Thread thread : _acceptors) for (Thread thread : _acceptors)
{ {
@ -404,7 +404,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
*/ */
public boolean isAccepting() public boolean isAccepting()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _accepting; return _accepting;
} }
@ -412,7 +412,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
public void setAccepting(boolean accepting) public void setAccepting(boolean accepting)
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_accepting = accepting; _accepting = accepting;
_setAccepting.signalAll(); _setAccepting.signalAll();
@ -422,7 +422,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
@Override @Override
public ConnectionFactory getConnectionFactory(String protocol) public ConnectionFactory getConnectionFactory(String protocol)
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _factories.get(StringUtil.asciiToLowerCase(protocol)); return _factories.get(StringUtil.asciiToLowerCase(protocol));
} }
@ -431,7 +431,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
@Override @Override
public <T> T getConnectionFactory(Class<T> factoryType) public <T> T getConnectionFactory(Class<T> factoryType)
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
for (ConnectionFactory f : _factories.values()) for (ConnectionFactory f : _factories.values())
{ {
@ -683,7 +683,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{ {
while (isRunning()) while (isRunning())
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (!_accepting && isRunning()) if (!_accepting && isRunning())
{ {

View File

@ -57,7 +57,7 @@ import org.eclipse.jetty.util.component.AttributeContainerMap;
import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ShutdownThread; import org.eclipse.jetty.util.thread.ShutdownThread;
import org.eclipse.jetty.util.thread.ThreadPool; import org.eclipse.jetty.util.thread.ThreadPool;
@ -84,8 +84,7 @@ public class Server extends HandlerWrapper implements Attributes
private ErrorHandler _errorHandler; private ErrorHandler _errorHandler;
private RequestLog _requestLog; private RequestLog _requestLog;
private boolean _dryRun; private boolean _dryRun;
private final AutoLock _dateLock = new AutoLock();
private final Locker _dateLocker = new Locker();
private volatile DateField _dateField; private volatile DateField _dateField;
public Server() public Server()
@ -326,7 +325,7 @@ public class Server extends HandlerWrapper implements Attributes
if (df == null || df._seconds != seconds) if (df == null || df._seconds != seconds)
{ {
try (Locker.Lock lock = _dateLocker.lock()) try (AutoLock lock = _dateLock.lock())
{ {
df = _dateField; df = _dateField;
if (df == null || df._seconds != seconds) if (df == null || df._seconds != seconds)
@ -419,6 +418,7 @@ public class Server extends HandlerWrapper implements Attributes
_connectors.stream().filter(LifeCycle::isRunning).map(Object.class::cast).forEach(LifeCycle::stop); _connectors.stream().filter(LifeCycle::isRunning).map(Object.class::cast).forEach(LifeCycle::stop);
} }
} }
mex.ifExceptionThrow(); mex.ifExceptionThrow();
LOG.info(String.format("Started %s @%dms", this, Uptime.getUptime())); LOG.info(String.format("Started %s @%dms", this, Uptime.getUptime()));
} }

View File

@ -48,7 +48,7 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
/** /**
* <p>Handler to limit the threads per IP address for DOS protection</p> * <p>Handler to limit the threads per IP address for DOS protection</p>
@ -241,7 +241,7 @@ public class ThreadLimitHandler extends HandlerWrapper
} }
} }
protected Remote getRemote(Request baseRequest) private Remote getRemote(Request baseRequest)
{ {
Remote remote = (Remote)baseRequest.getAttribute(REMOTE); Remote remote = (Remote)baseRequest.getAttribute(REMOTE);
if (remote != null) if (remote != null)
@ -329,11 +329,11 @@ public class ThreadLimitHandler extends HandlerWrapper
return (comma >= 0) ? forwardedFor.substring(comma + 1).trim() : forwardedFor; return (comma >= 0) ? forwardedFor.substring(comma + 1).trim() : forwardedFor;
} }
private final class Remote implements Closeable private static final class Remote implements Closeable
{ {
private final String _ip; private final String _ip;
private final int _limit; private final int _limit;
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private int _permits; private int _permits;
private Deque<CompletableFuture<Closeable>> _queue = new ArrayDeque<>(); private Deque<CompletableFuture<Closeable>> _queue = new ArrayDeque<>();
private final CompletableFuture<Closeable> _permitted = CompletableFuture.completedFuture(this); private final CompletableFuture<Closeable> _permitted = CompletableFuture.completedFuture(this);
@ -346,7 +346,7 @@ public class ThreadLimitHandler extends HandlerWrapper
public CompletableFuture<Closeable> acquire() public CompletableFuture<Closeable> acquire()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
// Do we have available passes? // Do we have available passes?
if (_permits < _limit) if (_permits < _limit)
@ -358,16 +358,16 @@ public class ThreadLimitHandler extends HandlerWrapper
} }
// No pass available, so queue a new future // No pass available, so queue a new future
CompletableFuture<Closeable> pass = new CompletableFuture<Closeable>(); CompletableFuture<Closeable> pass = new CompletableFuture<>();
_queue.addLast(pass); _queue.addLast(pass);
return pass; return pass;
} }
} }
@Override @Override
public void close() throws IOException public void close()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
// reduce the allocated passes // reduce the allocated passes
_permits--; _permits--;
@ -396,14 +396,14 @@ public class ThreadLimitHandler extends HandlerWrapper
@Override @Override
public String toString() public String toString()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return String.format("R[ip=%s,p=%d,l=%d,q=%d]", _ip, _permits, _limit, _queue.size()); return String.format("R[ip=%s,p=%d,l=%d,q=%d]", _ip, _permits, _limit, _queue.size());
} }
} }
} }
private final class RFC7239 extends QuotedCSV private static final class RFC7239 extends QuotedCSV
{ {
String _for; String _for;

View File

@ -29,7 +29,7 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker.Lock; import org.eclipse.jetty.util.thread.AutoLock;
/** /**
* AbstractSessionCache * AbstractSessionCache
@ -116,9 +116,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
*/ */
public abstract Session newSession(HttpServletRequest request, SessionData data); public abstract Session newSession(HttpServletRequest request, SessionData data);
/**
* @see org.eclipse.jetty.server.session.SessionCache#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long)
*/
@Override @Override
public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs) public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
{ {
@ -175,7 +172,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
/** /**
* PlaceHolder * PlaceHolder
*/ */
protected class PlaceHolderSession extends Session protected static class PlaceHolderSession extends Session
{ {
/** /**
@ -205,9 +202,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
return _handler; return _handler;
} }
/**
* @see org.eclipse.jetty.server.session.SessionCache#initialize(org.eclipse.jetty.server.session.SessionContext)
*/
@Override @Override
public void initialize(SessionContext context) public void initialize(SessionContext context)
{ {
@ -254,9 +248,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
return _sessionDataStore; return _sessionDataStore;
} }
/**
* @see org.eclipse.jetty.server.session.SessionCache#setSessionDataStore(org.eclipse.jetty.server.session.SessionDataStore)
*/
@Override @Override
public void setSessionDataStore(SessionDataStore sessionStore) public void setSessionDataStore(SessionDataStore sessionStore)
{ {
@ -264,9 +255,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
_sessionDataStore = sessionStore; _sessionDataStore = sessionStore;
} }
/**
* @see org.eclipse.jetty.server.session.SessionCache#getEvictionPolicy()
*/
@ManagedAttribute(value = "session eviction policy", readonly = true) @ManagedAttribute(value = "session eviction policy", readonly = true)
@Override @Override
public int getEvictionPolicy() public int getEvictionPolicy()
@ -278,8 +266,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* -1 means we never evict inactive sessions. * -1 means we never evict inactive sessions.
* 0 means we evict a session after the last request for it exits * 0 means we evict a session after the last request for it exits
* &gt;0 is the number of seconds after which we evict inactive sessions from the cache * &gt;0 is the number of seconds after which we evict inactive sessions from the cache
*
* @see org.eclipse.jetty.server.session.SessionCache#setEvictionPolicy(int)
*/ */
@Override @Override
public void setEvictionPolicy(int evictionTimeout) public void setEvictionPolicy(int evictionTimeout)
@ -314,7 +300,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* If a session's data cannot be loaded from the store without error, remove * If a session's data cannot be loaded from the store without error, remove
* it from the persistent store. * it from the persistent store.
* *
* @param removeUnloadableSessions if <code>true</code> unloadable sessions will be removed from session store * @param removeUnloadableSessions if {@code true} unloadable sessions will be removed from session store
*/ */
@Override @Override
public void setRemoveUnloadableSessions(boolean removeUnloadableSessions) public void setRemoveUnloadableSessions(boolean removeUnloadableSessions)
@ -340,8 +326,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* If the session object is not in this session store, try getting * If the session object is not in this session store, try getting
* the data for it from a SessionDataStore associated with the * the data for it from a SessionDataStore associated with the
* session manager. The usage count of the session is incremented. * session manager. The usage count of the session is incremented.
*
* @see org.eclipse.jetty.server.session.SessionCache#get(java.lang.String)
*/ */
@Override @Override
public Session get(String id) throws Exception public Session get(String id) throws Exception
@ -357,8 +341,8 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* *
* @param id The session to retrieve * @param id The session to retrieve
* @param enter if true, the usage count of the session will be incremented * @param enter if true, the usage count of the session will be incremented
* @return * @return the Session object
* @throws Exception * @throws Exception if the session cannot be retrieved
*/ */
protected Session getAndEnter(String id, boolean enter) throws Exception protected Session getAndEnter(String id, boolean enter) throws Exception
{ {
@ -379,7 +363,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
//didn't get a session, try and create one and put in a placeholder for it //didn't get a session, try and create one and put in a placeholder for it
PlaceHolderSession phs = new PlaceHolderSession(_handler, new SessionData(id, null, null, 0, 0, 0, 0)); PlaceHolderSession phs = new PlaceHolderSession(_handler, new SessionData(id, null, null, 0, 0, 0, 0));
Lock phsLock = phs.lock(); AutoLock phsLock = phs.lock();
Session s = doPutIfAbsent(id, phs); Session s = doPutIfAbsent(id, phs);
if (s == null) if (s == null)
{ {
@ -395,7 +379,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
break; break;
} }
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
//swap it in instead of the placeholder //swap it in instead of the placeholder
boolean success = doReplace(id, phs, session); boolean success = doReplace(id, phs, session);
@ -432,7 +416,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
{ {
//my placeholder didn't win, check the session returned //my placeholder didn't win, check the session returned
phsLock.close(); phsLock.close();
try (Lock lock = s.lock()) try (AutoLock lock = s.lock())
{ {
//is it a placeholder? or is a non-resident session? In both cases, chuck it away and start again //is it a placeholder? or is a non-resident session? In both cases, chuck it away and start again
if (!s.isResident() || s instanceof PlaceHolderSession) if (!s.isResident() || s instanceof PlaceHolderSession)
@ -451,7 +435,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
else else
{ {
//check the session returned //check the session returned
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again //is it a placeholder? or is it passivated? In both cases, chuck it away and start again
if (!session.isResident() || session instanceof PlaceHolderSession) if (!session.isResident() || session instanceof PlaceHolderSession)
@ -512,8 +496,8 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* Add an entirely new session (created by the application calling Request.getSession(true)) * Add an entirely new session (created by the application calling Request.getSession(true))
* to the cache. The usage count of the fresh session is incremented. * to the cache. The usage count of the fresh session is incremented.
* *
* @param id the id * @param id the session id
* @param session * @param session the new session to add
*/ */
@Override @Override
public void add(String id, Session session) throws Exception public void add(String id, Session session) throws Exception
@ -521,7 +505,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
if (id == null || session == null) if (id == null || session == null)
throw new IllegalArgumentException("Add key=" + id + " session=" + (session == null ? "null" : session.getId())); throw new IllegalArgumentException("Add key=" + id + " session=" + (session == null ? "null" : session.getId()));
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
if (session.getSessionHandler() == null) if (session.getSessionHandler() == null)
throw new IllegalStateException("Session " + id + " is not managed"); throw new IllegalStateException("Session " + id + " is not managed");
@ -552,7 +536,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
if (session == null) if (session == null)
return; return;
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
//only write the session out at this point if the attributes changed. If only //only write the session out at this point if the attributes changed. If only
//the lastAccess/expiry time changed defer the write until the last request exits //the lastAccess/expiry time changed defer the write until the last request exits
@ -575,9 +559,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
} }
} }
/**
* @deprecated
*/
@Override @Override
public void put(String id, Session session) throws Exception public void put(String id, Session session) throws Exception
{ {
@ -596,8 +577,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* *
* If the evictionPolicy == SessionCache.EVICT_ON_SESSION_EXIT then after we have saved * If the evictionPolicy == SessionCache.EVICT_ON_SESSION_EXIT then after we have saved
* the session, we evict it from the cache. * the session, we evict it from the cache.
*
* @see org.eclipse.jetty.server.session.SessionCache#release(java.lang.String, org.eclipse.jetty.server.session.Session)
*/ */
@Override @Override
public void release(String id, Session session) throws Exception public void release(String id, Session session) throws Exception
@ -605,7 +584,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
if (id == null || session == null) if (id == null || session == null)
throw new IllegalArgumentException("Put key=" + id + " session=" + (session == null ? "null" : session.getId())); throw new IllegalArgumentException("Put key=" + id + " session=" + (session == null ? "null" : session.getId()));
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
if (session.getSessionHandler() == null) if (session.getSessionHandler() == null)
throw new IllegalStateException("Session " + id + " is not managed"); throw new IllegalStateException("Session " + id + " is not managed");
@ -684,7 +663,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* it will check with the data store. * it will check with the data store.
* *
* @throws Exception the Exception * @throws Exception the Exception
* @see org.eclipse.jetty.server.session.SessionCache#exists(java.lang.String)
*/ */
@Override @Override
public boolean exists(String id) throws Exception public boolean exists(String id) throws Exception
@ -693,7 +671,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
Session s = doGet(id); Session s = doGet(id);
if (s != null) if (s != null)
{ {
try (Lock lock = s.lock()) try (AutoLock lock = s.lock())
{ {
//wait for the lock and check the validity of the session //wait for the lock and check the validity of the session
return s.isValid(); return s.isValid();
@ -707,8 +685,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
/** /**
* Check to see if this cache contains an entry for the session * Check to see if this cache contains an entry for the session
* corresponding to the session id. * corresponding to the session id.
*
* @see org.eclipse.jetty.server.session.SessionCache#contains(java.lang.String)
*/ */
@Override @Override
public boolean contains(String id) throws Exception public boolean contains(String id) throws Exception
@ -719,8 +695,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
/** /**
* Remove a session object from this store and from any backing store. * Remove a session object from this store and from any backing store.
*
* @see org.eclipse.jetty.server.session.SessionCache#delete(java.lang.String)
*/ */
@Override @Override
public Session delete(String id) throws Exception public Session delete(String id) throws Exception
@ -745,9 +719,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
return doDelete(id); return doDelete(id);
} }
/**
* @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set)
*/
@Override @Override
public Set<String> checkExpiration(Set<String> candidates) public Set<String> checkExpiration(Set<String> candidates)
{ {
@ -795,7 +766,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("Checking for idle {}", session.getId()); LOG.debug("Checking for idle {}", session.getId());
try (Lock s = session.lock()) try (AutoLock lock = session.lock())
{ {
if (getEvictionPolicy() > 0 && session.isIdleLongerThan(getEvictionPolicy()) && if (getEvictionPolicy() > 0 && session.isIdleLongerThan(getEvictionPolicy()) &&
session.isValid() && session.isResident() && session.getRequests() <= 0) session.isValid() && session.isResident() && session.getRequests() <= 0)
@ -858,7 +829,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
if (session == null) if (session == null)
return; return;
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
final String oldId = session.getId(); final String oldId = session.getId();
session.checkValidForWrite(); //can't change id on invalid session session.checkValidForWrite(); //can't change id on invalid session
@ -881,9 +852,6 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
} }
} }
/**
* @see org.eclipse.jetty.server.session.SessionCache#setSaveOnInactiveEviction(boolean)
*/
@Override @Override
public void setSaveOnInactiveEviction(boolean saveOnEvict) public void setSaveOnInactiveEviction(boolean saveOnEvict)
{ {

View File

@ -36,8 +36,7 @@ import javax.servlet.http.HttpSessionEvent;
import org.eclipse.jetty.io.CyclicTimeout; import org.eclipse.jetty.io.CyclicTimeout;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.Locker.Lock;
/** /**
* Session * Session
@ -73,15 +72,11 @@ public class Session implements SessionHandler.SessionIf
VALID, INVALID, INVALIDATING, CHANGING VALID, INVALID, INVALIDATING, CHANGING
} }
;
public enum IdState public enum IdState
{ {
SET, CHANGING SET, CHANGING
} }
;
protected final SessionData _sessionData; // the actual data associated with protected final SessionData _sessionData; // the actual data associated with
// a session // a session
@ -98,7 +93,7 @@ public class Session implements SessionHandler.SessionIf
protected State _state = State.VALID; // state of the session:valid,invalid protected State _state = State.VALID; // state of the session:valid,invalid
// or being invalidated // or being invalidated
protected Locker _lock = new Locker(); // sync lock protected AutoLock _lock = new AutoLock();
protected Condition _stateChangeCompleted = _lock.newCondition(); protected Condition _stateChangeCompleted = _lock.newCondition();
protected boolean _resident = false; protected boolean _resident = false;
protected final SessionInactivityTimer _sessionInactivityTimer; protected final SessionInactivityTimer _sessionInactivityTimer;
@ -128,7 +123,7 @@ public class Session implements SessionHandler.SessionIf
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
//handle what to do with the session after the timer expired //handle what to do with the session after the timer expired
getSessionHandler().sessionInactivityTimerExpired(Session.this, now); getSessionHandler().sessionInactivityTimerExpired(Session.this, now);
try (Lock lock = Session.this.lock()) try (AutoLock lock = Session.this.lock())
{ {
//grab the lock and check what happened to the session: if it didn't get evicted and //grab the lock and check what happened to the session: if it didn't get evicted and
//it hasn't expired, we need to reset the timer //it hasn't expired, we need to reset the timer
@ -213,7 +208,7 @@ public class Session implements SessionHandler.SessionIf
*/ */
public long getRequests() public long getRequests()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _requests; return _requests;
} }
@ -226,7 +221,7 @@ public class Session implements SessionHandler.SessionIf
protected void cookieSet() protected void cookieSet()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
_sessionData.setCookieSet(_sessionData.getAccessed()); _sessionData.setCookieSet(_sessionData.getAccessed());
} }
@ -234,7 +229,7 @@ public class Session implements SessionHandler.SessionIf
protected void use() protected void use()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
_requests++; _requests++;
@ -247,7 +242,7 @@ public class Session implements SessionHandler.SessionIf
protected boolean access(long time) protected boolean access(long time)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
if (!isValid() || !isResident()) if (!isValid() || !isResident())
return false; return false;
@ -267,7 +262,7 @@ public class Session implements SessionHandler.SessionIf
protected void complete() protected void complete()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
_requests--; _requests--;
@ -294,7 +289,7 @@ public class Session implements SessionHandler.SessionIf
*/ */
protected boolean isExpiredAt(long time) protected boolean isExpiredAt(long time)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _sessionData.isExpiredAt(time); return _sessionData.isExpiredAt(time);
} }
@ -309,7 +304,7 @@ public class Session implements SessionHandler.SessionIf
protected boolean isIdleLongerThan(int sec) protected boolean isIdleLongerThan(int sec)
{ {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return ((_sessionData.getAccessed() + (sec * 1000)) <= now); return ((_sessionData.getAccessed() + (sec * 1000)) <= now);
} }
@ -350,7 +345,7 @@ public class Session implements SessionHandler.SessionIf
*/ */
public void unbindValue(java.lang.String name, Object value) public void unbindValue(java.lang.String name, Object value)
{ {
if (value != null && value instanceof HttpSessionBindingListener) if (value instanceof HttpSessionBindingListener)
((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this, name)); ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this, name));
} }
@ -363,7 +358,7 @@ public class Session implements SessionHandler.SessionIf
*/ */
public void bindValue(java.lang.String name, Object value) public void bindValue(java.lang.String name, Object value)
{ {
if (value != null && value instanceof HttpSessionBindingListener) if (value instanceof HttpSessionBindingListener)
((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this, name)); ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this, name));
} }
@ -383,9 +378,9 @@ public class Session implements SessionHandler.SessionIf
try try
{ {
HttpSessionEvent event = new HttpSessionEvent(this); HttpSessionEvent event = new HttpSessionEvent(this);
for (Iterator<String> iter = _sessionData.getKeys().iterator(); iter.hasNext();) for (String name : _sessionData.getKeys())
{ {
Object value = _sessionData.getAttribute(iter.next()); Object value = _sessionData.getAttribute(name);
if (value instanceof HttpSessionActivationListener) if (value instanceof HttpSessionActivationListener)
{ {
HttpSessionActivationListener listener = (HttpSessionActivationListener)value; HttpSessionActivationListener listener = (HttpSessionActivationListener)value;
@ -405,9 +400,9 @@ public class Session implements SessionHandler.SessionIf
public void willPassivate() public void willPassivate()
{ {
HttpSessionEvent event = new HttpSessionEvent(this); HttpSessionEvent event = new HttpSessionEvent(this);
for (Iterator<String> iter = _sessionData.getKeys().iterator(); iter.hasNext();) for (String name : _sessionData.getKeys())
{ {
Object value = _sessionData.getAttribute(iter.next()); Object value = _sessionData.getAttribute(name);
if (value instanceof HttpSessionActivationListener) if (value instanceof HttpSessionActivationListener)
{ {
HttpSessionActivationListener listener = (HttpSessionActivationListener)value; HttpSessionActivationListener listener = (HttpSessionActivationListener)value;
@ -418,7 +413,7 @@ public class Session implements SessionHandler.SessionIf
public boolean isValid() public boolean isValid()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.VALID; return _state == State.VALID;
} }
@ -426,21 +421,15 @@ public class Session implements SessionHandler.SessionIf
public boolean isInvalid() public boolean isInvalid()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.INVALID || _state == State.INVALIDATING; return _state == State.INVALID || _state == State.INVALIDATING;
} }
} }
public boolean isChanging()
{
checkLocked();
return _state == State.CHANGING;
}
public long getCookieSetTime() public long getCookieSetTime()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _sessionData.getCookieSet(); return _sessionData.getCookieSet();
} }
@ -449,7 +438,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public long getCreationTime() throws IllegalStateException public long getCreationTime() throws IllegalStateException
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
return _sessionData.getCreated(); return _sessionData.getCreated();
@ -462,7 +451,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public String getId() public String getId()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _sessionData.getId(); return _sessionData.getId();
} }
@ -489,7 +478,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public long getLastAccessedTime() public long getLastAccessedTime()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
if (isInvalid()) if (isInvalid())
{ {
@ -516,7 +505,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public void setMaxInactiveInterval(int secs) public void setMaxInactiveInterval(int secs)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
_sessionData.setMaxInactiveMs((long)secs * 1000L); _sessionData.setMaxInactiveMs((long)secs * 1000L);
_sessionData.calcAndSetExpiry(); _sessionData.calcAndSetExpiry();
@ -549,7 +538,7 @@ public class Session implements SessionHandler.SessionIf
{ {
long time = 0; long time = 0;
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
long remaining = _sessionData.getExpiry() - now; long remaining = _sessionData.getExpiry() - now;
long maxInactive = _sessionData.getMaxInactiveMs(); long maxInactive = _sessionData.getMaxInactiveMs();
@ -613,7 +602,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public int getMaxInactiveInterval() public int getMaxInactiveInterval()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
long maxInactiveMs = _sessionData.getMaxInactiveMs(); long maxInactiveMs = _sessionData.getMaxInactiveMs();
return (int)(maxInactiveMs < 0 ? -1 : maxInactiveMs / 1000); return (int)(maxInactiveMs < 0 ? -1 : maxInactiveMs / 1000);
@ -643,8 +632,6 @@ public class Session implements SessionHandler.SessionIf
*/ */
protected void checkValidForWrite() throws IllegalStateException protected void checkValidForWrite() throws IllegalStateException
{ {
checkLocked();
if (_state == State.INVALID) if (_state == State.INVALID)
throw new IllegalStateException("Not valid for write: id=" + _sessionData.getId() + throw new IllegalStateException("Not valid for write: id=" + _sessionData.getId() +
" created=" + _sessionData.getCreated() + " created=" + _sessionData.getCreated() +
@ -668,8 +655,6 @@ public class Session implements SessionHandler.SessionIf
*/ */
protected void checkValidForRead() throws IllegalStateException protected void checkValidForRead() throws IllegalStateException
{ {
checkLocked();
if (_state == State.INVALID) if (_state == State.INVALID)
throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() + throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() +
" created=" + _sessionData.getCreated() + " created=" + _sessionData.getCreated() +
@ -685,19 +670,13 @@ public class Session implements SessionHandler.SessionIf
throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() + " not resident"); throw new IllegalStateException("Invalid for read: id=" + _sessionData.getId() + " not resident");
} }
protected void checkLocked() throws IllegalStateException
{
if (!_lock.isLocked())
throw new IllegalStateException("Session not locked");
}
/** /**
* @see javax.servlet.http.HttpSession#getAttribute(java.lang.String) * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String)
*/ */
@Override @Override
public Object getAttribute(String name) public Object getAttribute(String name)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
return _sessionData.getAttribute(name); return _sessionData.getAttribute(name);
@ -711,7 +690,7 @@ public class Session implements SessionHandler.SessionIf
@Deprecated(since = "Servlet API 2.2") @Deprecated(since = "Servlet API 2.2")
public Object getValue(String name) public Object getValue(String name)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
return _sessionData.getAttribute(name); return _sessionData.getAttribute(name);
@ -724,11 +703,11 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public Enumeration<String> getAttributeNames() public Enumeration<String> getAttributeNames()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
final Iterator<String> itor = _sessionData.getKeys().iterator(); final Iterator<String> itor = _sessionData.getKeys().iterator();
return new Enumeration<String>() return new Enumeration<>()
{ {
@Override @Override
@ -764,7 +743,7 @@ public class Session implements SessionHandler.SessionIf
@Deprecated(since = "Servlet API 2.2") @Deprecated(since = "Servlet API 2.2")
public String[] getValueNames() throws IllegalStateException public String[] getValueNames() throws IllegalStateException
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
Iterator<String> itor = _sessionData.getKeys().iterator(); Iterator<String> itor = _sessionData.getKeys().iterator();
@ -787,7 +766,7 @@ public class Session implements SessionHandler.SessionIf
public void setAttribute(String name, Object value) public void setAttribute(String name, Object value)
{ {
Object old = null; Object old = null;
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
// if session is not valid, don't accept the set // if session is not valid, don't accept the set
checkValidForWrite(); checkValidForWrite();
@ -841,7 +820,7 @@ public class Session implements SessionHandler.SessionIf
String id = null; String id = null;
String extendedId = null; String extendedId = null;
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
while (true) while (true)
{ {
@ -877,7 +856,7 @@ public class Session implements SessionHandler.SessionIf
String newId = _handler._sessionIdManager.renewSessionId(id, extendedId, request); String newId = _handler._sessionIdManager.renewSessionId(id, extendedId, request);
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -955,7 +934,7 @@ public class Session implements SessionHandler.SessionIf
* *
* @return the lock * @return the lock
*/ */
public Lock lock() public AutoLock lock()
{ {
return _lock.lock(); return _lock.lock();
} }
@ -967,7 +946,7 @@ public class Session implements SessionHandler.SessionIf
{ {
boolean result = false; boolean result = false;
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
while (true) while (true)
@ -1026,7 +1005,7 @@ public class Session implements SessionHandler.SessionIf
*/ */
protected void finishInvalidate() throws IllegalStateException protected void finishInvalidate() throws IllegalStateException
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
try try
{ {
@ -1064,7 +1043,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public boolean isNew() throws IllegalStateException public boolean isNew() throws IllegalStateException
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
checkValidForRead(); checkValidForRead();
return _newSession; return _newSession;
@ -1073,7 +1052,7 @@ public class Session implements SessionHandler.SessionIf
public void setIdChanged(boolean changed) public void setIdChanged(boolean changed)
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
_idChanged = changed; _idChanged = changed;
} }
@ -1081,7 +1060,7 @@ public class Session implements SessionHandler.SessionIf
public boolean isIdChanged() public boolean isIdChanged()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return _idChanged; return _idChanged;
} }
@ -1099,9 +1078,6 @@ public class Session implements SessionHandler.SessionIf
return _sessionData; return _sessionData;
} }
/**
*
*/
public void setResident(boolean resident) public void setResident(boolean resident)
{ {
_resident = resident; _resident = resident;
@ -1118,7 +1094,7 @@ public class Session implements SessionHandler.SessionIf
@Override @Override
public String toString() public String toString()
{ {
try (Lock lock = _lock.lock()) try (AutoLock lock = _lock.lock())
{ {
return String.format("%s@%x{id=%s,x=%s,req=%d,res=%b}", return String.format("%s@%x{id=%s,x=%s,req=%d,res=%b}",
getClass().getSimpleName(), getClass().getSimpleName(),

View File

@ -126,11 +126,11 @@ public interface SessionCache extends LifeCycle
* @param id the session id * @param id the session id
* @param session the current session object * @param session the current session object
* @throws Exception if any error occurred * @throws Exception if any error occurred
* @deprecated @see release * @deprecated use {@link #release(String, Session)} instead
*/ */
@Deprecated
void put(String id, Session session) throws Exception; void put(String id, Session session) throws Exception;
/** /**
* Finish using a Session. This is called by the SessionHandler * Finish using a Session. This is called by the SessionHandler
* once a request is finished with a Session. SessionCache * once a request is finished with a Session. SessionCache

View File

@ -29,7 +29,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.SessionCookieConfig; import javax.servlet.SessionCookieConfig;
@ -59,7 +58,7 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.statistic.CounterStatistic; import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic; import org.eclipse.jetty.util.statistic.SampleStatistic;
import org.eclipse.jetty.util.thread.Locker.Lock; import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler; import org.eclipse.jetty.util.thread.Scheduler;
@ -1285,7 +1284,7 @@ public class SessionHandler extends ScopedHandler
//1. valid //1. valid
//2. expired //2. expired
//3. idle //3. idle
try (Lock lock = session.lock()) try (AutoLock lock = session.lock())
{ {
if (session.getRequests() > 0) if (session.getRequests() > 0)
return; //session can't expire or be idle if there is a request in it return; //session can't expire or be idle if there is a request in it

View File

@ -20,7 +20,7 @@ package org.eclipse.jetty.util;
import java.io.IOException; import java.io.IOException;
import org.eclipse.jetty.util.thread.Locker; import org.eclipse.jetty.util.thread.AutoLock;
/** /**
* This specialized callback implements a pattern that allows * This specialized callback implements a pattern that allows
@ -125,7 +125,7 @@ public abstract class IteratingCallback implements Callback
SUCCEEDED SUCCEEDED
} }
private Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private State _state; private State _state;
private boolean _iterate; private boolean _iterate;
@ -188,35 +188,31 @@ public abstract class IteratingCallback implements Callback
{ {
boolean process = false; boolean process = false;
loop: try (AutoLock lock = _lock.lock())
while (true)
{ {
try (Locker.Lock lock = _locker.lock()) switch (_state)
{ {
switch (_state) case PENDING:
{ case CALLED:
case PENDING: // process will be called when callback is handled
case CALLED: break;
// process will be called when callback is handled
break loop;
case IDLE: case IDLE:
_state = State.PROCESSING; _state = State.PROCESSING;
process = true; process = true;
break loop; break;
case PROCESSING: case PROCESSING:
_iterate = true; _iterate = true;
break loop; break;
case FAILED: case FAILED:
case SUCCEEDED: case SUCCEEDED:
break loop; break;
case CLOSED: case CLOSED:
default: default:
throw new IllegalStateException(toString()); throw new IllegalStateException(toString());
}
} }
} }
if (process) if (process)
@ -243,11 +239,11 @@ public abstract class IteratingCallback implements Callback
catch (Throwable x) catch (Throwable x)
{ {
failed(x); failed(x);
break processing; break;
} }
// acted on the action we have just received // acted on the action we have just received
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -295,18 +291,11 @@ public abstract class IteratingCallback implements Callback
case CALLED: case CALLED:
{ {
switch (action) if (action != Action.SCHEDULED)
{ throw new IllegalStateException(String.format("%s[action=%s]", this, action));
case SCHEDULED: // we lost the race, so we have to keep processing
{ _state = State.PROCESSING;
// we lost the race, so we have to keep processing continue processing;
_state = State.PROCESSING;
continue processing;
}
default:
throw new IllegalStateException(String.format("%s[action=%s]", this, action));
}
} }
case SUCCEEDED: case SUCCEEDED:
@ -335,7 +324,7 @@ public abstract class IteratingCallback implements Callback
public void succeeded() public void succeeded()
{ {
boolean process = false; boolean process = false;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -375,7 +364,7 @@ public abstract class IteratingCallback implements Callback
public void failed(Throwable x) public void failed(Throwable x)
{ {
boolean failure = false; boolean failure = false;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -405,7 +394,7 @@ public abstract class IteratingCallback implements Callback
public void close() public void close()
{ {
String failure = null; String failure = null;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -434,7 +423,7 @@ public abstract class IteratingCallback implements Callback
*/ */
boolean isIdle() boolean isIdle()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.IDLE; return _state == State.IDLE;
} }
@ -442,7 +431,7 @@ public abstract class IteratingCallback implements Callback
public boolean isClosed() public boolean isClosed()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.CLOSED; return _state == State.CLOSED;
} }
@ -453,7 +442,7 @@ public abstract class IteratingCallback implements Callback
*/ */
public boolean isFailed() public boolean isFailed()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.FAILED; return _state == State.FAILED;
} }
@ -464,7 +453,7 @@ public abstract class IteratingCallback implements Callback
*/ */
public boolean isSucceeded() public boolean isSucceeded()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _state == State.SUCCEEDED; return _state == State.SUCCEEDED;
} }
@ -481,7 +470,7 @@ public abstract class IteratingCallback implements Callback
*/ */
public boolean reset() public boolean reset()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {

View File

@ -22,37 +22,27 @@ import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
/** /**
* <p>Convenience auto closeable {@link java.util.concurrent.locks.ReentrantLock} wrapper.</p> * Reentrant lock that can be used in a try-with-resources statement.
*
* <pre> * <pre>
* try (Locker.Lock lock = locker.lock()) * try (AutoLock lock = this.lock.lock())
* { * {
* // something * // Something
* } * }
* </pre> * </pre>
*/ */
public class Locker public class AutoLock implements AutoCloseable
{ {
private final ReentrantLock _lock = new ReentrantLock(); private final ReentrantLock _lock = new ReentrantLock();
private final Lock _unlock = new Lock();
/** /**
* <p>Acquires the lock.</p> * <p>Acquires the lock.</p>
* *
* @return the lock to unlock * @return this AutoLock for unlocking
*/ */
public Lock lock() public AutoLock lock()
{ {
_lock.lock(); _lock.lock();
return _unlock; return this;
}
/**
* @return whether this lock has been acquired
*/
public boolean isLocked()
{
return _lock.isLocked();
} }
/** /**
@ -63,15 +53,15 @@ public class Locker
return _lock.newCondition(); return _lock.newCondition();
} }
/** // Package-private for testing only.
* <p>The unlocker object that unlocks when it is closed.</p> boolean isLocked()
*/
public class Lock implements AutoCloseable
{ {
@Override return _lock.isLocked();
public void close() }
{
_lock.unlock(); @Override
} public void close()
{
_lock.unlock();
} }
} }

View File

@ -248,8 +248,8 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
private class ReservedThread implements Runnable private class ReservedThread implements Runnable
{ {
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private final Condition _wakeup = _locker.newCondition(); private final Condition _wakeup = _lock.newCondition();
private boolean _starting = true; private boolean _starting = true;
private Runnable _task = null; private Runnable _task = null;
@ -258,7 +258,7 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} offer {}", this, task); LOG.debug("{} offer {}", this, task);
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_task = task; _task = task;
_wakeup.signal(); _wakeup.signal();
@ -280,7 +280,7 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
{ {
boolean idle = false; boolean idle = false;
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (_task == null) if (_task == null)
{ {

View File

@ -22,11 +22,10 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.ExecutionStrategy; import org.eclipse.jetty.util.thread.ExecutionStrategy;
import org.eclipse.jetty.util.thread.Invocable; import org.eclipse.jetty.util.thread.Invocable;
import org.eclipse.jetty.util.thread.Invocable.InvocationType; import org.eclipse.jetty.util.thread.Invocable.InvocationType;
import org.eclipse.jetty.util.thread.Locker;
import org.eclipse.jetty.util.thread.Locker.Lock;
/** /**
* <p>A strategy where the thread that produces will always run the resulting task.</p> * <p>A strategy where the thread that produces will always run the resulting task.</p>
@ -45,7 +44,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
{ {
private static final Logger LOG = Log.getLogger(ExecuteProduceConsume.class); private static final Logger LOG = Log.getLogger(ExecuteProduceConsume.class);
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private final Runnable _runProduce = new RunProduce(); private final Runnable _runProduce = new RunProduce();
private final Producer _producer; private final Producer _producer;
private final Executor _executor; private final Executor _executor;
@ -67,7 +66,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
LOG.debug("{} execute", this); LOG.debug("{} execute", this);
boolean produce = false; boolean produce = false;
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
// If we are idle and a thread is not producing // If we are idle and a thread is not producing
if (_idle) if (_idle)
@ -98,7 +97,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} spawning", this); LOG.debug("{} spawning", this);
boolean dispatch = false; boolean dispatch = false;
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
if (_idle) if (_idle)
dispatch = true; dispatch = true;
@ -115,7 +114,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} run", this); LOG.debug("{} run", this);
boolean produce = false; boolean produce = false;
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
_pending = false; _pending = false;
if (!_idle && !_producing) if (!_idle && !_producing)
@ -145,7 +144,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
LOG.debug("{} produced {}", this, task); LOG.debug("{} produced {}", this, task);
boolean dispatch = false; boolean dispatch = false;
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
// Finished producing // Finished producing
_producing = false; _producing = false;
@ -191,13 +190,12 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
// Run the task. // Run the task.
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} run {}", this, task); LOG.debug("{} run {}", this, task);
if (task != null) task.run();
task.run();
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("{} ran {}", this, task); LOG.debug("{} ran {}", this, task);
// Once we have run the task, we can try producing again. // Once we have run the task, we can try producing again.
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
// Is another thread already producing or we are now idle? // Is another thread already producing or we are now idle?
if (_producing || _idle) if (_producing || _idle)
@ -212,7 +210,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
public Boolean isIdle() public Boolean isIdle()
{ {
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
return _idle; return _idle;
} }
@ -223,7 +221,7 @@ public class ExecuteProduceConsume implements ExecutionStrategy, Runnable
{ {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("EPC "); builder.append("EPC ");
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
builder.append(_idle ? "Idle/" : ""); builder.append(_idle ? "Idle/" : "");
builder.append(_producing ? "Prod/" : ""); builder.append(_producing ? "Prod/" : "");

View File

@ -22,8 +22,8 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.ExecutionStrategy; import org.eclipse.jetty.util.thread.ExecutionStrategy;
import org.eclipse.jetty.util.thread.Locker;
/** /**
* <p>A strategy where the caller thread iterates over task production, submitting each * <p>A strategy where the caller thread iterates over task production, submitting each
@ -33,7 +33,7 @@ public class ProduceConsume implements ExecutionStrategy, Runnable
{ {
private static final Logger LOG = Log.getLogger(ExecuteProduceConsume.class); private static final Logger LOG = Log.getLogger(ExecuteProduceConsume.class);
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private final Producer _producer; private final Producer _producer;
private final Executor _executor; private final Executor _executor;
private State _state = State.IDLE; private State _state = State.IDLE;
@ -47,7 +47,7 @@ public class ProduceConsume implements ExecutionStrategy, Runnable
@Override @Override
public void produce() public void produce()
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -73,7 +73,7 @@ public class ProduceConsume implements ExecutionStrategy, Runnable
if (task == null) if (task == null)
{ {
try (Locker.Lock lock = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {

View File

@ -22,11 +22,10 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.ExecutionStrategy; import org.eclipse.jetty.util.thread.ExecutionStrategy;
import org.eclipse.jetty.util.thread.Invocable; import org.eclipse.jetty.util.thread.Invocable;
import org.eclipse.jetty.util.thread.Invocable.InvocationType; import org.eclipse.jetty.util.thread.Invocable.InvocationType;
import org.eclipse.jetty.util.thread.Locker;
import org.eclipse.jetty.util.thread.Locker.Lock;
/** /**
* <p>A strategy where the caller thread iterates over task production, submitting each * <p>A strategy where the caller thread iterates over task production, submitting each
@ -36,7 +35,7 @@ public class ProduceExecuteConsume implements ExecutionStrategy
{ {
private static final Logger LOG = Log.getLogger(ProduceExecuteConsume.class); private static final Logger LOG = Log.getLogger(ProduceExecuteConsume.class);
private final Locker _locker = new Locker(); private final AutoLock _lock = new AutoLock();
private final Producer _producer; private final Producer _producer;
private final Executor _executor; private final Executor _executor;
private State _state = State.IDLE; private State _state = State.IDLE;
@ -50,7 +49,7 @@ public class ProduceExecuteConsume implements ExecutionStrategy
@Override @Override
public void produce() public void produce()
{ {
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -77,7 +76,7 @@ public class ProduceExecuteConsume implements ExecutionStrategy
if (task == null) if (task == null)
{ {
try (Lock locked = _locker.lock()) try (AutoLock lock = _lock.lock())
{ {
switch (_state) switch (_state)
{ {
@ -106,7 +105,7 @@ public class ProduceExecuteConsume implements ExecutionStrategy
@Override @Override
public void dispatch() public void dispatch()
{ {
_executor.execute(() -> produce()); _executor.execute(this::produce);
} }
private enum State private enum State

View File

@ -26,19 +26,15 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
public class LockerTest public class AutoLockTest
{ {
public LockerTest()
{
}
@Test @Test
public void testLocked() public void testLocked()
{ {
Locker lock = new Locker(); AutoLock lock = new AutoLock();
assertFalse(lock.isLocked()); assertFalse(lock.isLocked());
try (Locker.Lock l = lock.lock()) try (AutoLock l = lock.lock())
{ {
assertTrue(lock.isLocked()); assertTrue(lock.isLocked());
} }
@ -53,10 +49,10 @@ public class LockerTest
@Test @Test
public void testLockedException() public void testLockedException()
{ {
Locker lock = new Locker(); AutoLock lock = new AutoLock();
assertFalse(lock.isLocked()); assertFalse(lock.isLocked());
try (Locker.Lock l = lock.lock()) try (AutoLock l = lock.lock())
{ {
assertTrue(lock.isLocked()); assertTrue(lock.isLocked());
throw new Exception(); throw new Exception();
@ -76,27 +72,23 @@ public class LockerTest
@Test @Test
public void testContend() throws Exception public void testContend() throws Exception
{ {
final Locker lock = new Locker(); AutoLock lock = new AutoLock();
final CountDownLatch held0 = new CountDownLatch(1); final CountDownLatch held0 = new CountDownLatch(1);
final CountDownLatch hold0 = new CountDownLatch(1); final CountDownLatch hold0 = new CountDownLatch(1);
Thread thread0 = new Thread() Thread thread0 = new Thread(() ->
{ {
@Override try (AutoLock l = lock.lock())
public void run()
{ {
try (Locker.Lock l = lock.lock()) held0.countDown();
{ hold0.await();
held0.countDown();
hold0.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} }
}; catch (InterruptedException e)
{
e.printStackTrace();
}
});
thread0.start(); thread0.start();
held0.await(); held0.await();
@ -104,22 +96,18 @@ public class LockerTest
final CountDownLatch held1 = new CountDownLatch(1); final CountDownLatch held1 = new CountDownLatch(1);
final CountDownLatch hold1 = new CountDownLatch(1); final CountDownLatch hold1 = new CountDownLatch(1);
Thread thread1 = new Thread() Thread thread1 = new Thread(() ->
{ {
@Override try (AutoLock l = lock.lock())
public void run()
{ {
try (Locker.Lock l = lock.lock()) held1.countDown();
{ hold1.await();
held1.countDown();
hold1.await();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} }
}; catch (InterruptedException e)
{
e.printStackTrace();
}
});
thread1.start(); thread1.start();
// thread1 will be spinning here // thread1 will be spinning here
assertFalse(held1.await(100, TimeUnit.MILLISECONDS)); assertFalse(held1.await(100, TimeUnit.MILLISECONDS));

View File

@ -34,11 +34,13 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StacklessLogging; import org.eclipse.jetty.util.log.StacklessLogging;
import org.eclipse.jetty.util.thread.Locker.Lock; import org.eclipse.jetty.util.thread.AutoLock;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
/** /**
@ -94,7 +96,7 @@ public class IdleSessionTest
ContentResponse response = client.GET(url + "?action=init"); ContentResponse response = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertEquals(HttpServletResponse.SC_OK, response.getStatus());
String sessionCookie = response.getHeaders().get("Set-Cookie"); String sessionCookie = response.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null); assertNotNull(sessionCookie);
//ensure request has finished being handled //ensure request has finished being handled
synchronizer.await(5, TimeUnit.SECONDS); synchronizer.await(5, TimeUnit.SECONDS);
@ -148,7 +150,7 @@ public class IdleSessionTest
response = client.GET(url + "?action=init"); response = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertEquals(HttpServletResponse.SC_OK, response.getStatus());
sessionCookie = response.getHeaders().get("Set-Cookie"); sessionCookie = response.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null); assertNotNull(sessionCookie);
id = TestServer.extractSessionId(sessionCookie); id = TestServer.extractSessionId(sessionCookie);
//ensure request has finished being handled //ensure request has finished being handled
@ -220,7 +222,7 @@ public class IdleSessionTest
ContentResponse response = client.GET(url + "?action=init"); ContentResponse response = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertEquals(HttpServletResponse.SC_OK, response.getStatus());
String sessionCookie = response.getHeaders().get("Set-Cookie"); String sessionCookie = response.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null); assertNotNull(sessionCookie);
//ensure request has finished being handled //ensure request has finished being handled
synchronizer.await(5, TimeUnit.SECONDS); synchronizer.await(5, TimeUnit.SECONDS);
@ -265,7 +267,7 @@ public class IdleSessionTest
response = client.GET(url + "?action=init"); response = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertEquals(HttpServletResponse.SC_OK, response.getStatus());
sessionCookie = response.getHeaders().get("Set-Cookie"); sessionCookie = response.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null); assertNotNull(sessionCookie);
id = TestServer.extractSessionId(sessionCookie); id = TestServer.extractSessionId(sessionCookie);
//ensure request has finished being handled //ensure request has finished being handled
@ -317,7 +319,7 @@ public class IdleSessionTest
session.setAttribute("value", 1); session.setAttribute("value", 1);
originalId = session.getId(); originalId = session.getId();
Session s = (Session)session; Session s = (Session)session;
try (Lock lock = s.lock()) try (AutoLock lock = s.lock())
{ {
assertTrue(s.isResident()); assertTrue(s.isResident());
} }
@ -326,21 +328,21 @@ public class IdleSessionTest
else if ("test".equals(action)) else if ("test".equals(action))
{ {
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
assertTrue(session != null); assertNotNull(session);
assertTrue(originalId.equals(session.getId())); assertEquals(originalId, session.getId());
Session s = (Session)session; Session s = (Session)session;
try (Lock lock = s.lock();) try (AutoLock lock = s.lock())
{ {
assertTrue(s.isResident()); assertTrue(s.isResident());
} }
Integer v = (Integer)session.getAttribute("value"); Integer v = (Integer)session.getAttribute("value");
session.setAttribute("value", v.intValue() + 1); session.setAttribute("value", v + 1);
_session = session; _session = session;
} }
else if ("testfail".equals(action)) else if ("testfail".equals(action))
{ {
HttpSession session = request.getSession(false); HttpSession session = request.getSession(false);
assertTrue(session == null); assertNull(session);
_session = session; _session = session;
} }
} }