Am 03.01.2022 um 15:00 schrieb Mark Thomas:
On 03/01/2022 13:05, Rainer Jung wrote:

Am 03.01.2022 um 12:33 schrieb Mark Thomas:
On 03/01/2022 11:17, Rainer Jung wrote:
Thanks Marc.

In the meantime, I can also say, that it happens for TC 8.5 using JSSE or OpenSSL and NIO or NIO2. I did not try APR.

Unfortunately I can still reproduce on TC 8.5 even without the sync patch you mentioned below.

Drat. Can you post the stack trace for the deadlock you see in that case? Just to save me trying to recreate it.

Thanks,

Mark

Double checking revealed: although I did compile the new class the test ran with the unpatched one, line numbers in the stacks showed line 621 which is the synchronized line in the original Stream.java. Sorry for the confiusion. So you asuumption is confirmed, that that change triggers it.

Good news. Thanks for the update.

Will try with TC 9 original head code next.

I think you'll need to run with useAsyncIO="false" to be able to trigger this on 9.0.x.

I can reproduce this with a debugger on 8.5.x and I think I have a possible fix. If you replace:

synchronized (state) { ...

with

synchronized (this) { ...

can you still trigger the deadlock on 8.5.x?

Mark

Unfortunately it seems the deadlock has just moved:

Found one Java-level deadlock:
=============================
"http-nio-127.0.0.1-auto-1-exec-6":
waiting to lock monitor 0x0000000100d2f5e8 (object 0xffffffff41f8a898, a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper),
  which is held by "http-nio-127.0.0.1-auto-1-exec-4"
"http-nio-127.0.0.1-auto-1-exec-4":
waiting to lock monitor 0x0000000100d31e78 (object 0xffffffff41b11e48, a org.apache.coyote.http2.Stream),
  which is held by "http-nio-127.0.0.1-auto-1-exec-6"

Java stack information for the threads listed above:
===================================================

"http-nio-127.0.0.1-auto-1-exec-6":
at org.apache.coyote.http2.Http2UpgradeHandler.sendStreamReset(Http2UpgradeHandler.java:558) - waiting to lock <0xffffffff41f8a898> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
        at org.apache.coyote.http2.Stream.close(Stream.java:623)
        - locked <0xffffffff41b11e48> (a org.apache.coyote.http2.Stream)
at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:85) - locked <0xffffffff41b3c008> (a org.apache.coyote.http2.StreamProcessor) at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-127.0.0.1-auto-1-exec-4":
        at org.apache.coyote.http2.Stream.close(Stream.java:622)
- waiting to lock <0xffffffff41b11e48> (a org.apache.coyote.http2.Stream) at org.apache.coyote.http2.Http2UpgradeHandler.upgradeDispatch(Http2UpgradeHandler.java:350) at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:849) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1677) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) - locked <0xffffffff41f8a898> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

My current Stream.java looks like this:

617 // Sync ensures that if the call to sendReset() triggers resets 618 // in other threads, that the RST frame associated with this 619 // thread is sent before the RST frames associated with those
 620                 // threads.
 621                 synchronized (this) {
 622                     state.sendReset();
 623                     handler.sendStreamReset(se);
 624                 }
 625                 cancelAllocationRequests();
 626                 if (inputBuffer != null) {
 627                     inputBuffer.swallowUnread();
 628                 }


% git diff
diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java
index fffd2403e8..16a64bd6c5 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -618,7 +618,7 @@ class Stream extends AbstractNonZeroStream implements HeaderEmitter { // in other threads, that the RST frame associated with this // thread is sent before the RST frames associated with those
                 // threads.
-                synchronized (state) {
+                synchronized (this) {
                     state.sendReset();
                     handler.sendStreamReset(se);
                 }

Regards,

Rainer

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to