Repository: quarkusio/quarkus
Issue: Thread locked after  stress test

**Describe the bug**
(Describe the problem clearly and concisely.)

I did a simple stress test，then the program keeps giving alarm log.
```log
21:59:37 WARNING [io.ve.co.im.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-9,5,main]=Thread[vert.x-worker-thread-9,5,main] has been blocked for 3382564 ms, time limit is 60000 ms: io.vertx.core.VertxException: Thread blocked
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:502)
        at io.quarkus.resteasy.runtime.standalone.VertxBlockingOutput.awaitWriteable(VertxBlockingOutput.java:111)
        at io.quarkus.resteasy.runtime.standalone.VertxBlockingOutput.write(VertxBlockingOutput.java:71)
        at io.quarkus.resteasy.runtime.standalone.VertxHttpResponse.writeBlocking(VertxHttpResponse.java:179)
        at io.quarkus.resteasy.runtime.standalone.VertxOutputStream.write(VertxOutputStream.java:69)
        at io.quarkus.resteasy.runtime.standalone.VertxOutputStream.write(VertxOutputStream.java:42)
        at org.jboss.resteasy.util.CommitHeaderOutputStream.write(CommitHeaderOutputStream.java:64)
        at org.jboss.resteasy.util.DelegatingOutputStream.write(DelegatingOutputStream.java:42)
        at org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.writeTo(JsonBindingProvider.java:137)
        at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:193)
        at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:64)
        at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:155)
        at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$2(ServerResponseWriter.java:156)
        at org.jboss.resteasy.core.ServerResponseWriter$$Lambda$417/1780592217.run(Unknown Source)
        at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:404)
        at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:232)
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:97)
        at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:70)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:578)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:508)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252)
        at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$332/1061176646.run(Unknown Source)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153)
        at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$338/1804746610.get(Unknown Source)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:109)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatchRequestContext(VertxRequestHandler.java:84)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.lambda$handle$0(VertxRequestHandler.java:71)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$$Lambda$313/2064123549.handle(Unknown Source)
        at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:316)
        at io.vertx.core.impl.ContextImpl$$Lambda$327/865803395.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)
```
After the test ,All requests are unresponsive . 
jstack log: 
```
"mysql-cj-abandoned-connection-cleanup" #54 daemon prio=5 os_prio=0 tid=0x00007ff55c042800 nid=0xfaa in Object.wait() [0x00007ff60e3e8000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
	- locked <0x00000006ca58bd08> (a java.lang.ref.ReferenceQueue$Lock)
	at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:85)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- <0x00000006ca58b8f8> (a java.util.concurrent.ThreadPoolExecutor$Worker)

"vert.x-worker-thread-12" #53 prio=5 os_prio=0 tid=0x00007ff58c007000 nid=0xfa9 in Object.wait() [0x00007ff60e8e8000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at io.quarkus.resteasy.runtime.standalone.VertxBlockingOutput.awaitWriteable(VertxBlockingOutput.java:111)
	at io.quarkus.resteasy.runtime.standalone.VertxBlockingOutput.write(VertxBlockingOutput.java:71)
	- locked <0x00000006c8739c58> (a io.vertx.core.http.impl.Http1xServerConnection)
	at io.quarkus.resteasy.runtime.standalone.VertxHttpResponse.writeBlocking(VertxHttpResponse.java:179)
	at io.quarkus.resteasy.runtime.standalone.VertxOutputStream.write(VertxOutputStream.java:69)
	at io.quarkus.resteasy.runtime.standalone.VertxOutputStream.write(VertxOutputStream.java:42)
	at org.jboss.resteasy.util.CommitHeaderOutputStream.write(CommitHeaderOutputStream.java:64)
	at org.jboss.resteasy.util.DelegatingOutputStream.write(DelegatingOutputStream.java:42)
	at org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.writeTo(JsonBindingProvider.java:137)
	at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:193)
	at org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:64)
	at org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:155)
	at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$2(ServerResponseWriter.java:156)
	at org.jboss.resteasy.core.ServerResponseWriter$$Lambda$417/1780592217.run(Unknown Source)
	at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:404)
	- locked <0x00000007bea82098> (a org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl)
	at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:232)
	at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:97)
	at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:70)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:578)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:508)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252)
	at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$332/1061176646.run(Unknown Source)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153)
	at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$338/1804746610.get(Unknown Source)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
	- locked <0x00000007bea82130> (a org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238)
	at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:109)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatchRequestContext(VertxRequestHandler.java:84)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.lambda$handle$0(VertxRequestHandler.java:71)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$$Lambda$313/2064123549.handle(Unknown Source)
	at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:316)
	at io.vertx.core.impl.ContextImpl$$Lambda$327/865803395.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- <0x00000006c8863b08> (a java.util.concurrent.ThreadPoolExecutor$Worker)
```

**Expected behavior**
(Describe the expected behavior clearly and concisely.)

**Actual behavior**
(Describe the actual behavior clearly and concisely.)


**To Reproduce**
Steps to reproduce the behavior:
1.  My program was modified from hibernate-orm-panache-resteasy in quickstart. I add a restful service returns all records of  the table，there are 800 records in the table.
```java
    @GET
    public List<Student> findAll() {
        List<Student> list = Student.findAll().list();
        if (list == null) {
            throw new WebApplicationException("Fruit  does not exist.", 404);
        }
        return list;
    }
```
2. Then  run in JVM mode.
3. Did a simple stress test .
```shell
wrk -t12 -c2000 -d30s  http://10.32.1.***:8888/rest/students/
```

**Configuration**
```properties
# Add your application.properties here, if applicable.
quarkus.datasource.url=jdbc:mysql://10.32.1.***:3306/xyz
quarkus.datasource.driver=com.mysql.cj.jdbc.Driver
```
```xml
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-mysql</artifactId>
    </dependency>
```
**Screenshots**
(If applicable, add screenshots to help explain your problem.)

**Environment (please complete the following information):**
 - Output of `uname -a` or `ver`:  
Linux ***** 3.10.0-862.3.3.el7.x86_64 #1 SMP Fri Jun 15 04:15:27 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
 - Output of `java -version`: 
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

 - GraalVM version (if different from Java): 
 - Quarkus version or git rev: 1.0.0.CR1

**Additional context**

**The full jstack  dump info**
[jstack-l.txt](https://github.com/quarkusio/quarkus/files/3841662/jstack-l.txt)


Changed files:
extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxBlockingOutput.java
extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxOutputStream.java

diff --git a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxBlockingOutput.java b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxBlockingOutput.java
index bbb7e882f7b..fafae708f2f 100644
--- a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxBlockingOutput.java
+++ b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxBlockingOutput.java
@@ -68,11 +68,18 @@ public void write(ByteBuf data, boolean last) throws IOException {
         try {
             //do all this in the same lock
             synchronized (request.connection()) {
-                awaitWriteable();
-                if (last) {
-                    request.response().end(createBuffer(data));
-                } else {
-                    request.response().write(createBuffer(data));
+                try {
+                    awaitWriteable();
+                    if (last) {
+                        request.response().end(createBuffer(data));
+                    } else {
+                        request.response().write(createBuffer(data));
+                    }
+                } catch (Exception e) {
+                    if (data != null && data.refCnt() > 0) {
+                        data.release();
+                    }
+                    throw new IOException("Failed to write", e);
                 }
             }
         } finally {
@@ -95,16 +102,21 @@ private void awaitWriteable() throws IOException {
             if (Context.isOnEventLoopThread()) {
                 throw new IOException("Attempting a blocking write on io thread");
             }
+            if (request.response().closed()) {
+                throw new IOException("Connection has been closed");
+            }
             if (!drainHandlerRegistered) {
                 drainHandlerRegistered = true;
-                request.response().drainHandler(new Handler<Void>() {
+                Handler<Void> handler = new Handler<Void>() {
                     @Override
                     public void handle(Void event) {
                         if (waitingForDrain) {
                             request.connection().notifyAll();
                         }
                     }
-                });
+                };
+                request.response().drainHandler(handler);
+                request.response().closeHandler(handler);
             }
             try {
                 waitingForDrain = true;
diff --git a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxOutputStream.java b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxOutputStream.java
index a4ca581b378..8e626aceb26 100644
--- a/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxOutputStream.java
+++ b/extensions/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/standalone/VertxOutputStream.java
@@ -66,12 +66,13 @@ public void write(final byte[] b, final int off, final int len) throws IOExcepti
                 rem -= toWrite;
                 idx += toWrite;
                 if (!buffer.isWritable()) {
-                    response.writeBlocking(buffer, false);
+                    ByteBuf tmpBuf = buffer;
                     this.pooledBuffer = buffer = allocator.allocateBuffer();
+                    response.writeBlocking(tmpBuf, false);
                 }
             }
         } catch (Exception e) {
-            if (buffer != null) {
+            if (buffer != null && buffer.refCnt() > 0) {
                 buffer.release();
             }
             throw new IOException(e);