From d86f261f6b1f85ac6098d0c4149803e5fb051f16 Mon Sep 17 00:00:00 2001 From: Will Hedgecock Date: Fri, 18 Feb 2022 11:25:26 -0600 Subject: [PATCH] Add method to allow users to add application shutdown hooks --- .../com/fazecast/jSerialComm/SerialPort.java | 31 +++++++++++++++++++ .../fazecast/jSerialComm/SerialPortTest.java | 3 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/fazecast/jSerialComm/SerialPort.java b/src/main/java/com/fazecast/jSerialComm/SerialPort.java index be443b4..fcae98a 100644 --- a/src/main/java/com/fazecast/jSerialComm/SerialPort.java +++ b/src/main/java/com/fazecast/jSerialComm/SerialPort.java @@ -36,8 +36,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; /** * This class provides native access to serial ports and devices without requiring external libraries or tools. @@ -52,6 +54,7 @@ public final class SerialPort // Static initializer loads correct native library for this machine static private final String versionString = "2.9.1"; static private final String tmpdirAppIdProperty = "fazecast.jSerialComm.appid"; + static private List shutdownHooks = new ArrayList(); static private volatile boolean isAndroid = false; static private volatile boolean isWindows = false; static private volatile boolean isShuttingDown = false; @@ -406,6 +409,17 @@ public final class SerialPort { public void run() { + // Run any user-specified shutdown hooks + try { + for (Thread hook : shutdownHooks) + { + hook.start(); + hook.join(); + } + } + catch (InterruptedException e) {} + + // Un-initialize the native library isShuttingDown = true; uninitializeLibrary(); } @@ -443,6 +457,23 @@ public final class SerialPort */ static public final String getVersion() { return versionString; } + /** + * Registers a shutdown hook that will run just before the application fully closes, due to either + * exiting normally or in response to a user interrupt such as Ctrl+C. + *

+ * These hooks can be used to carry out any final serial port operations that should be executed to + * ensure graceful disconnection or device shutdown. + *

+ * There is no need to add a shutdown hook just to close all open ports, as this is done automatically + * by the library; however, any special reads, writes, or port handling that should take place prior + * to closing of the ports should be handled in a shutdown hook registered with this method. + * + * @param hook A {@link java.lang.Thread} object that will run just before the application shuts down. + * @see java.lang.Runtime#addShutdownHook(Thread) + * @see java.lang.Thread + */ + static public final synchronized void addShutdownHook(Thread hook) { shutdownHooks.add(hook); } + /** * Returns a list of all available serial ports on this machine. *

diff --git a/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java index 9a7388b..c637549 100644 --- a/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java +++ b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java @@ -2,7 +2,7 @@ * SerialPortTest.java * * Created on: Feb 27, 2015 - * Last Updated on: Jan 28, 2022 + * Last Updated on: Feb 18, 2022 * Author: Will Hedgecock * * Copyright (C) 2012-2022 Fazecast, Inc. @@ -84,6 +84,7 @@ public class SerialPortTest static public void main(String[] args) { System.out.println("\nUsing Library Version v" + SerialPort.getVersion()); + SerialPort.addShutdownHook(new Thread() { public void run() { System.out.println("\nRunning shutdown hook"); } }); SerialPort[] ports = SerialPort.getCommPorts(); System.out.println("\nAvailable Ports:\n"); for (int i = 0; i < ports.length; ++i)