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()
|
||||
{
|
||||
int q;
|
||||
ByteBuffer b;
|
||||
Object b;
|
||||
String o;
|
||||
try (AutoLock lock = _lock.lock())
|
||||
try (AutoLock lock = _lock.tryLock())
|
||||
{
|
||||
q = _inQ.size();
|
||||
b = _inQ.peek();
|
||||
o = BufferUtil.toDetailString(_out);
|
||||
boolean held = lock.isHeldByCurrentThread();
|
||||
q = held ? _inQ.size() : -1;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -546,16 +546,18 @@ public class HttpChannelState implements HttpChannel, Components
|
|||
@Override
|
||||
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(),
|
||||
hashCode(),
|
||||
_handling,
|
||||
_handled,
|
||||
_streamSendState,
|
||||
_callbackCompleted,
|
||||
_request);
|
||||
held ? _handling : "?",
|
||||
held ? _handled : "?",
|
||||
held ? _streamSendState : "?",
|
||||
held ? _callbackCompleted : "?",
|
||||
held ? _request : "?"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1270,6 +1272,7 @@ public class HttpChannelState implements HttpChannel, Components
|
|||
* <p>
|
||||
* 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}.
|
||||
*
|
||||
* @param x The reason for the failure.
|
||||
*/
|
||||
@Override
|
||||
|
@ -1498,6 +1501,7 @@ public class HttpChannelState implements HttpChannel, Components
|
|||
|
||||
/**
|
||||
* Called when the {@link Handler} (or it's delegates) fail the request handling.
|
||||
*
|
||||
* @param failure The reason for the failure.
|
||||
*/
|
||||
@Override
|
||||
|
@ -1679,6 +1683,7 @@ public class HttpChannelState implements HttpChannel, Components
|
|||
|
||||
/**
|
||||
* Called when the error write in {@link HttpChannelState.ChannelCallback#failed(Throwable)} fails.
|
||||
*
|
||||
* @param x The reason for the failure.
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
package org.eclipse.jetty.util.thread;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
|
@ -30,6 +31,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||
*/
|
||||
public class AutoLock implements AutoCloseable, Serializable
|
||||
{
|
||||
@Serial
|
||||
private static final long serialVersionUID = 3300696774541816341L;
|
||||
|
||||
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
|
||||
* @see ReentrantLock#isHeldByCurrentThread()
|
||||
*/
|
||||
public boolean isHeldByCurrentThread()
|
||||
{
|
||||
|
@ -71,7 +89,8 @@ public class AutoLock implements AutoCloseable, Serializable
|
|||
@Override
|
||||
public void close()
|
||||
{
|
||||
_lock.unlock();
|
||||
if (isHeldByCurrentThread())
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,6 +120,12 @@ public class AutoLock implements AutoCloseable, Serializable
|
|||
return (WithCondition)super.lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoLock.WithCondition tryLock()
|
||||
{
|
||||
return (WithCondition)super.tryLock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Condition#signal()
|
||||
*/
|
||||
|
@ -118,8 +143,8 @@ public class AutoLock implements AutoCloseable, Serializable
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Condition#await()
|
||||
* @throws InterruptedException if the current thread is interrupted
|
||||
* @see Condition#await()
|
||||
*/
|
||||
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 unit the time unit
|
||||
* @return false if the waiting time elapsed
|
||||
* @throws InterruptedException if the current thread is interrupted
|
||||
* @see Condition#await(long, TimeUnit)
|
||||
*/
|
||||
public boolean await(long time, TimeUnit unit) throws InterruptedException
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue