mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-03 04:19:12 +00:00
Merge pull request #4068 from eclipse/jetty-10.0.x-4058-autolock
Fixes #4058 - Review Locker.
This commit is contained in:
commit
d91ee54627
@ -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();
|
||||||
|
@ -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())
|
||||||
{
|
{
|
||||||
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
* >0 is the number of seconds after which we evict inactive sessions from the cache
|
* >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)
|
||||||
{
|
{
|
||||||
|
@ -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(),
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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/" : "");
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user