Recycling pooled connection events are not emitted on the eventloop context associated with connection pool
### Version

it should be only in 4.0

Currently recycling pooled connection events are not emitted on the eventloop context associated with connection pool and are emitted on the caller thread which might cause a racy access to the states of connection pool
diff --git a/vertx-pg-client/src/test/java/io/vertx/pgclient/PgPoolTestBase.java b/vertx-pg-client/src/test/java/io/vertx/pgclient/PgPoolTestBase.java
index 529e505e..0ec4f5cd 100644
--- a/vertx-pg-client/src/test/java/io/vertx/pgclient/PgPoolTestBase.java
+++ b/vertx-pg-client/src/test/java/io/vertx/pgclient/PgPoolTestBase.java
@@ -55,15 +55,15 @@ public abstract class PgPoolTestBase extends PgTestBase {
 
   @Test
   public void testPool(TestContext ctx) {
-    int num = 1000;
+    int num = 5000;
     Async async = ctx.async(num);
     PgPool pool = createPool(options, 4);
     for (int i = 0;i < num;i++) {
       pool.getConnection(ctx.asyncAssertSuccess(conn -> {
-        conn.query("SELECT id, randomnumber from WORLD WHERE id = 1").execute(ar -> {
+        conn.query("SELECT id, randomnumber from WORLD").execute(ar -> {
           if (ar.succeeded()) {
             SqlResult result = ar.result();
-            ctx.assertEquals(1, result.size());
+            ctx.assertEquals(10000, result.size());
           } else {
             ctx.assertEquals("closed", ar.cause().getMessage());
           }
@@ -80,10 +80,10 @@ public abstract class PgPoolTestBase extends PgTestBase {
     Async async = ctx.async(num);
     PgPool pool = createPool(options, 4);
     for (int i = 0;i < num;i++) {
-      pool.query("SELECT id, randomnumber from WORLD WHERE id = 1").execute(ar -> {
+      pool.query("SELECT id, randomnumber from WORLD").execute(ar -> {
         if (ar.succeeded()) {
           SqlResult result = ar.result();
-          ctx.assertEquals(1, result.size());
+          ctx.assertEquals(10000, result.size());
         } else {
           ctx.assertEquals("closed", ar.cause().getMessage());
         }
diff --git a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionPool.java b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionPool.java
index 7c92c0e2..b9c115d9 100644
--- a/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionPool.java
+++ b/vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionPool.java
@@ -169,6 +169,14 @@ public class ConnectionPool {
 
     @Override
     public void close(Holder holder, Promise<Void> promise) {
+      if (context != null) {
+        context.dispatch(v -> doClose(holder, promise));
+      } else {
+        doClose(holder, promise);
+      }
+    }
+
+    private void doClose(Holder holder, Promise<Void> promise) {
       if (holder != this.holder) {
         String msg;
         if (this.holder == null) {
['vertx-pg-client/src/test/java/io/vertx/pgclient/PgPoolTestBase.java', 'vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/ConnectionPool.java']