static <T> Supplier<T> blocking(Supplier<T> supplier, boolean threadLocal) { // [#5377] In ThreadLocal contexts (e.g. when using ThreadLocalTransactionprovider), // no ManagedBlocker is needed as we're guaranteed by API contract to always // remain on the same thread. return threadLocal ? supplier : new Supplier<T>() { volatile T asyncResult; @Override public T get() { try { ForkJoinPool.managedBlock(new ManagedBlocker() { @Override public boolean block() { asyncResult = supplier.get(); return true; } @Override public boolean isReleasable() { return asyncResult != null; } }); } catch (InterruptedException e) { throw new RuntimeException(e); } return asyncResult; } }; }
@Override public final CompletionStage<Integer> executeAsync(Executor executor) { return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::execute), executor), () -> executor); }
@Override public final CompletionStage<Result<R>> fetchAsync(Executor executor) { return ExecutorProviderCompletionStage.of(CompletableFuture.supplyAsync(blocking(this::fetch), executor), () -> executor); }
@Override public CompletionStage<Result<Record>> fetchAsync(Executor executor, ResultSet rs) { return ExecutorProviderCompletionStage.of( CompletableFuture.supplyAsync(blocking(() -> fetch(rs)), executor), () -> executor ); }
@Override public CompletionStage<Result<Record>> fetchAsync(Executor executor, ResultSet rs, Class<?>... types) { return ExecutorProviderCompletionStage.of( CompletableFuture.supplyAsync(blocking(() -> fetch(rs, types)), executor), () -> executor ); }
@Override public CompletionStage<Result<Record>> fetchAsync(Executor executor, ResultSet rs, Field<?>... fields) { return ExecutorProviderCompletionStage.of( CompletableFuture.supplyAsync(blocking(() -> fetch(rs, fields)), executor), () -> executor ); }
@Override public CompletionStage<Result<Record>> fetchAsync(Executor executor, ResultSet rs, DataType<?>... types) { return ExecutorProviderCompletionStage.of( CompletableFuture.supplyAsync(blocking(() -> fetch(rs, types)), executor), () -> executor ); }
return blocking(() -> {