Skip to content

Commit

Permalink
Ensure that the task is not in the tasks queue when it is rejected fr…
Browse files Browse the repository at this point in the history
…om the executor

Closes eclipse-vertx#4900
  • Loading branch information
ahus1 committed Oct 13, 2023
1 parent d04371e commit 677ee8a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/main/java/io/vertx/core/impl/TaskQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.util.LinkedList;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.function.Consumer;

/**
Expand Down Expand Up @@ -124,11 +125,27 @@ public Consumer<Runnable> unschedule() {
*/
public void execute(Runnable task, Executor executor) {
synchronized (tasks) {
tasks.add(new ExecuteTask(task, executor));
if (this.currentExecutor == null) {
this.currentExecutor = executor;
executor.execute(runner);
if (currentExecutor == null) {
currentExecutor = executor;
try {
executor.execute(runner);
} catch (RejectedExecutionException e) {
currentExecutor = null;
throw e;
}
}
// Add the task after the runner has been accepted to the executor
// to cover the case of a rejected execution exception.
tasks.add(new ExecuteTask(task, executor));
}
}

/**
* Test if the task queue is empty and no current executor is running anymore.
*/
public boolean isEmpty() {
synchronized (tasks) {
return tasks.isEmpty() && currentExecutor == null;
}
}

Expand Down
34 changes: 34 additions & 0 deletions src/test/java/io/vertx/core/impl/TaskQueueTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.vertx.core.impl;

import org.assertj.core.api.Assertions;
import org.junit.Test;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;

import static org.assertj.core.api.Assertions.assertThatThrownBy;

/**
* @author Alexander Schwartz
*/
public class TaskQueueTest {

Executor executorThatAlwaysThrowsRejectedExceptions = new Executor() {
@Override
public void execute(Runnable command) {
throw new RejectedExecutionException();
}
};

TaskQueue taskQueue = new TaskQueue();

@Test
public void shouldNotHaveTaskInQueueWhenTaskHasBeenRejected() {
assertThatThrownBy(
() -> taskQueue.execute(new Thread(), executorThatAlwaysThrowsRejectedExceptions)
).isInstanceOf(RejectedExecutionException.class);

Assertions.assertThat(taskQueue.isEmpty()).isTrue();
}

}

0 comments on commit 677ee8a

Please sign in to comment.