[hal] Add HAL_Shutdown and simulation shutdown callbacks

This is useful for clean shutdown of simulation extensions.
This commit is contained in:
Peter Johnson
2020-09-04 08:59:26 -07:00
parent 0365557b25
commit f1b1bdb121
8 changed files with 65 additions and 0 deletions

View File

@@ -420,6 +420,8 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
return true;
}
void HAL_Shutdown(void) {}
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
const char* feature) {
if (feature == nullptr) {

View File

@@ -36,6 +36,18 @@ Java_edu_wpi_first_hal_HAL_initialize
return HAL_Initialize(timeout, mode);
}
/*
* Class: edu_wpi_first_hal_HAL
* Method: shutdown
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_HAL_shutdown
(JNIEnv*, jclass)
{
return HAL_Shutdown();
}
/*
* Class: edu_wpi_first_hal_HAL
* Method: hasMain

View File

@@ -25,7 +25,10 @@
*/
typedef int halsim_extension_init_func_t(void);
#ifdef __cplusplus
extern "C" {
#endif
/**
* Loads a single extension from a direct path.
*
@@ -82,5 +85,17 @@ void HAL_RegisterExtensionListener(void* param,
* @param showMessage true to show message, false to not.
*/
void HAL_SetShowExtensionsNotFoundMessages(HAL_Bool showMessage);
/**
* Registers a function to be called from HAL_Shutdown(). This is intended
* for use only by simulation extensions.
*
* @param param parameter data to pass to callback function
* @param func callback function
*/
void HAL_OnShutdown(void* param, void (*func)(void*));
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */

View File

@@ -149,6 +149,14 @@ uint64_t HAL_ExpandFPGATime(uint32_t unexpanded_lower, int32_t* status);
*/
HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode);
/**
* Call this to shut down HAL.
*
* This must be called at termination of the robot program to avoid potential
* segmentation faults with simulation extensions at exit.
*/
void HAL_Shutdown(void);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -7,8 +7,11 @@
#include "hal/HAL.h"
#include <vector>
#include <wpi/mutex.h>
#include <wpi/raw_ostream.h>
#include <wpi/spinlock.h>
#ifdef _WIN32
#include <Windows.h>
@@ -28,6 +31,8 @@
using namespace hal;
static HAL_RuntimeType runtimeType{HAL_Mock};
static wpi::spinlock gOnShutdownMutex;
static std::vector<std::pair<void*, void (*)(void*)>> gOnShutdown;
namespace hal {
namespace init {
@@ -312,6 +317,22 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
return true; // Add initialization if we need to at a later point
}
void HAL_Shutdown(void) {
std::vector<std::pair<void*, void (*)(void*)>> funcs;
{
std::scoped_lock lock(gOnShutdownMutex);
funcs.swap(gOnShutdown);
}
for (auto&& func : funcs) {
func.second(func.first);
}
}
void HAL_OnShutdown(void* param, void (*func)(void*)) {
std::scoped_lock lock(gOnShutdownMutex);
gOnShutdown.emplace_back(param, func);
}
int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
const char* feature) {
return 0; // Do nothing for now