Merge pull request #11306 from jetty/fix/jetty-12/11282/debug-deadlock
Fixes #11282 - Deadlocks with DEBUG logging enabled in jetty-server testing.
This commit is contained in:
commit
ef75595e8e
|
@ -492,13 +492,14 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
int q;
|
int q;
|
||||||
ByteBuffer b;
|
Object b;
|
||||||
String o;
|
String o;
|
||||||
try (AutoLock lock = _lock.lock())
|
try (AutoLock lock = _lock.tryLock())
|
||||||
{
|
{
|
||||||
q = _inQ.size();
|
boolean held = lock.isHeldByCurrentThread();
|
||||||
b = _inQ.peek();
|
q = held ? _inQ.size() : -1;
|
||||||
o = BufferUtil.toDetailString(_out);
|
b = held ? _inQ.peek() : "?";
|
||||||
|
o = held ? BufferUtil.toDetailString(_out) : "?";
|
||||||
}
|
}
|
||||||
return String.format("%s[q=%d,q[0]=%s,o=%s]", super.toString(), q, b, o);
|
return String.format("%s[q=%d,q[0]=%s,o=%s]", super.toString(), q, b, o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -546,16 +546,18 @@ public class HttpChannelState implements HttpChannel, Components
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
try (AutoLock ignored = _lock.lock())
|
try (AutoLock lock = _lock.tryLock())
|
||||||
{
|
{
|
||||||
return String.format("%s@%x{handling=%s, handled=%b, send=%s, completed=%b, request=%s}",
|
boolean held = lock.isHeldByCurrentThread();
|
||||||
|
return String.format("%s@%x{handling=%s, handled=%s, send=%s, completed=%s, request=%s}",
|
||||||
this.getClass().getSimpleName(),
|
this.getClass().getSimpleName(),
|
||||||
hashCode(),
|
hashCode(),
|
||||||
_handling,
|
held ? _handling : "?",
|
||||||
_handled,
|
held ? _handled : "?",
|
||||||
_streamSendState,
|
held ? _streamSendState : "?",
|
||||||
_callbackCompleted,
|
held ? _callbackCompleted : "?",
|
||||||
_request);
|
held ? _request : "?"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1270,6 +1272,7 @@ public class HttpChannelState implements HttpChannel, Components
|
||||||
* <p>
|
* <p>
|
||||||
* The implementation maintains the {@link #_streamSendState} before taking
|
* The implementation maintains the {@link #_streamSendState} before taking
|
||||||
* and serializing the call to the {@link #_writeCallback}, which was set by the call to {@code write}.
|
* and serializing the call to the {@link #_writeCallback}, which was set by the call to {@code write}.
|
||||||
|
*
|
||||||
* @param x The reason for the failure.
|
* @param x The reason for the failure.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1498,6 +1501,7 @@ public class HttpChannelState implements HttpChannel, Components
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the {@link Handler} (or it's delegates) fail the request handling.
|
* Called when the {@link Handler} (or it's delegates) fail the request handling.
|
||||||
|
*
|
||||||
* @param failure The reason for the failure.
|
* @param failure The reason for the failure.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -1679,6 +1683,7 @@ public class HttpChannelState implements HttpChannel, Components
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the error write in {@link HttpChannelState.ChannelCallback#failed(Throwable)} fails.
|
* Called when the error write in {@link HttpChannelState.ChannelCallback#failed(Throwable)} fails.
|
||||||
|
*
|
||||||
* @param x The reason for the failure.
|
* @param x The reason for the failure.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.thread;
|
package org.eclipse.jetty.util.thread;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
|
@ -30,6 +31,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
*/
|
*/
|
||||||
public class AutoLock implements AutoCloseable, Serializable
|
public class AutoLock implements AutoCloseable, Serializable
|
||||||
{
|
{
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 3300696774541816341L;
|
private static final long serialVersionUID = 3300696774541816341L;
|
||||||
|
|
||||||
private final ReentrantLock _lock = new ReentrantLock();
|
private final ReentrantLock _lock = new ReentrantLock();
|
||||||
|
@ -46,8 +48,24 @@ public class AutoLock implements AutoCloseable, Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ReentrantLock#isHeldByCurrentThread()
|
* <p>Tries to acquire the lock.</p>
|
||||||
|
* <p>Whether the lock was acquired can be tested
|
||||||
|
* with {@link #isHeldByCurrentThread()}.</p>
|
||||||
|
* <p>Typical usage of this method is in {@code toString()},
|
||||||
|
* to avoid deadlocks when the implementation needs to lock
|
||||||
|
* to retrieve a consistent state to produce the string.</p>
|
||||||
|
*
|
||||||
|
* @return this AutoLock for unlocking
|
||||||
|
*/
|
||||||
|
public AutoLock tryLock()
|
||||||
|
{
|
||||||
|
_lock.tryLock();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @return whether this lock is held by the current thread
|
* @return whether this lock is held by the current thread
|
||||||
|
* @see ReentrantLock#isHeldByCurrentThread()
|
||||||
*/
|
*/
|
||||||
public boolean isHeldByCurrentThread()
|
public boolean isHeldByCurrentThread()
|
||||||
{
|
{
|
||||||
|
@ -71,6 +89,7 @@ public class AutoLock implements AutoCloseable, Serializable
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
|
if (isHeldByCurrentThread())
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +120,12 @@ public class AutoLock implements AutoCloseable, Serializable
|
||||||
return (WithCondition)super.lock();
|
return (WithCondition)super.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AutoLock.WithCondition tryLock()
|
||||||
|
{
|
||||||
|
return (WithCondition)super.tryLock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Condition#signal()
|
* @see Condition#signal()
|
||||||
*/
|
*/
|
||||||
|
@ -118,8 +143,8 @@ public class AutoLock implements AutoCloseable, Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Condition#await()
|
|
||||||
* @throws InterruptedException if the current thread is interrupted
|
* @throws InterruptedException if the current thread is interrupted
|
||||||
|
* @see Condition#await()
|
||||||
*/
|
*/
|
||||||
public void await() throws InterruptedException
|
public void await() throws InterruptedException
|
||||||
{
|
{
|
||||||
|
@ -127,11 +152,11 @@ public class AutoLock implements AutoCloseable, Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Condition#await(long, TimeUnit)
|
|
||||||
* @param time the time to wait
|
* @param time the time to wait
|
||||||
* @param unit the time unit
|
* @param unit the time unit
|
||||||
* @return false if the waiting time elapsed
|
* @return false if the waiting time elapsed
|
||||||
* @throws InterruptedException if the current thread is interrupted
|
* @throws InterruptedException if the current thread is interrupted
|
||||||
|
* @see Condition#await(long, TimeUnit)
|
||||||
*/
|
*/
|
||||||
public boolean await(long time, TimeUnit unit) throws InterruptedException
|
public boolean await(long time, TimeUnit unit) throws InterruptedException
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue