com.diozero.util.Diozero Maven / Gradle / Ivy
The newest version!
package com.diozero.util;
/*-
* #%L
* Organisation: diozero
* Project: diozero - Core
* Filename: Diozero.java
*
* This file is part of the diozero project. More information about this project
* can be found at https://www.diozero.com/.
* %%
* Copyright (C) 2016 - 2024 diozero
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import org.tinylog.Logger;
import com.diozero.sbc.DeviceFactoryHelper;
public class Diozero {
public static final int UNKNOWN_VALUE = -1;
private static AtomicBoolean initialised = new AtomicBoolean(false);
private static AtomicBoolean shutdown = new AtomicBoolean(false);
private static List closeables = new ArrayList<>();
private static CountDownLatch doneSignal = new CountDownLatch(1);
private static String version;
public synchronized static String getVersion() {
if (version != null) {
return version;
}
// Load from the JAR file's META-INF/MANIFEST.MF Implementation-Version property
version = Diozero.class.getPackage().getImplementationVersion();
if (version != null) {
return version;
}
// Additional hack to get when running within an IDE and the MANIFEST.MF file
// isn't available
try (InputStream is = Diozero.class
.getResourceAsStream("/META-INF/maven/com.diozero/diozero-core/pom.properties")) {
if (is != null) {
Properties props = new Properties();
props.load(is);
version = props.getProperty("version");
}
} catch (IOException e) {
// Ignore
Logger.debug(e, "Failed to load pom.properties: {}", e);
}
if (version == null) {
version = "Unknown";
}
return version;
}
/**
* Initialise the diozero shutdown handler if not already initialised. Called
* from DeviceFactoryHelper.initialise(). Application code should not invoke
* this method.
*/
public static synchronized void initialiseShutdownHook() {
if (initialised.get()) {
return;
}
Runtime.getRuntime().addShutdownHook(new Thread(Diozero::shutdown, "diozero Shutdown Handler"));
initialised.set(true);
}
/**
* Register an object to be explicitly closed in the case of abnormal shutdown
*
* @param closeableArray Array of closeable objects to close on shutdown
*/
public static void registerForShutdown(AutoCloseable... closeableArray) {
for (AutoCloseable closeable : closeableArray) {
closeables.add(closeable);
}
}
/**
* Shutdown diozero.
*/
public static synchronized void shutdown() {
Logger.trace("shutdown - START");
if (shutdown.getAndSet(true)) {
Logger.trace("Already shutdown");
return;
}
// Stop all scheduled jobs
DiozeroScheduler.shutdownAll();
// First close all instances that have registered themselves with the
// DeviceFactoryHelper
if (closeables != null) {
closeables.forEach(closeable -> {
try {
closeable.close();
} catch (Exception e) {
// Ignore
}
});
closeables.clear();
}
// Then close the base native device factory which will close all
// InternalDeviceInterface instances that are still open
DeviceFactoryHelper.close();
// Notify any threads waiting on diozero to shutdown
doneSignal.countDown();
Logger.trace("shutdown - END");
}
public static void waitForShutdown() {
try {
doneSignal.await();
} catch (InterruptedException e) {
// Ignore
Logger.debug(e, "Interrupted: {}", e);
}
}
}