Skip to content

Commit

Permalink
[Java] Simplify SigInt and add a test.
Browse files Browse the repository at this point in the history
  • Loading branch information
vyazelenko committed Aug 8, 2023
1 parent a4fb8ed commit a747497
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 35 deletions.
25 changes: 4 additions & 21 deletions agrona/src/main/java/org/agrona/concurrent/SigInt.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,25 @@
*/
package org.agrona.concurrent;

import org.agrona.LangUtil;
import sun.misc.Signal;

import java.util.Objects;

/**
* Utility to allow the registration of a SIGINT handler that hides the unsupported {@link Signal} class.
*/
public class SigInt
{
public class SigInt {
/**
* Register a task to be run when a SIGINT is received.
*
* @param task to run on reception of the signal.
*/
public static void register(final Runnable task)
{
public static void register(final Runnable task) {
register("INT", task);
}

static void register(final String signalName, final Runnable task)
{
static void register(final String signalName, final Runnable task) {
Objects.requireNonNull(task);

Signal.handle(
new Signal(signalName),
(signal) ->
{
try
{
task.run();
}
catch (final Throwable t)
{
LangUtil.rethrowUnchecked(t);
}
});
Signal.handle(new Signal(signalName), (signal) -> task.run());
}
}
44 changes: 30 additions & 14 deletions agrona/src/test/java/org/agrona/concurrent/SigIntTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,24 @@
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.mockito.Mockito.*;

class SigIntTest
{
class SigIntTest {
@Test
void throwsNullPointerExceptionIfRunnableIsNull()
{
void throwsNullPointerExceptionIfRunnableIsNull() {
assertThrowsExactly(NullPointerException.class, () -> SigInt.register(null));
}

@ParameterizedTest
@ValueSource(strings = { "INT", "TERM" })
void shouldReplaceExistingSignalHandler(final String name) throws InterruptedException
{
@ValueSource(strings = {"INT", "TERM"})
void shouldReplaceExistingSignalHandler(final String name) throws InterruptedException {
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler =
Thread.getDefaultUncaughtExceptionHandler();
Thread.getDefaultUncaughtExceptionHandler();
final Signal signal = new Signal(name);
final SignalHandler originalHandler = Signal.handle(signal, sig -> {});

try
{
try {
final CountDownLatch executed = new CountDownLatch(1);
final Thread.UncaughtExceptionHandler exceptionHandler = mock(Thread.UncaughtExceptionHandler.class);
doAnswer((Answer<Void>)invocation ->
doAnswer((Answer<Void>) invocation ->
{
executed.countDown();
return null;
Expand All @@ -75,11 +71,31 @@ void shouldReplaceExistingSignalHandler(final String name) throws InterruptedExc
inOrder.verifyNoMoreInteractions();

verifyNoInteractions(oldHandler);
}
finally
{
} finally {
Thread.setDefaultUncaughtExceptionHandler(defaultUncaughtExceptionHandler);
Signal.handle(signal, originalHandler);
}
}

@ParameterizedTest
@ValueSource(strings = {"INT"})
void shouldReplaceExistingSignalHandlerNoException(final String name) throws InterruptedException {
final Signal signal = new Signal(name);
final SignalHandler originalHandler = Signal.handle(signal, sig -> {});

try {
final SignalHandler oldHandler = mock(SignalHandler.class);
Signal.handle(signal, oldHandler);

final CountDownLatch executed = new CountDownLatch(1);
SigInt.register(name, executed::countDown);

Signal.raise(signal);

executed.await();
verifyNoInteractions(oldHandler);
} finally {
Signal.handle(signal, originalHandler);
}
}
}

0 comments on commit a747497

Please sign in to comment.