mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpiutil] Add synchronization primitives
These enable more consistent use of synchronization across the native libraries. Users can create Event and Semaphore primitives, but in addition, libraries can set up any handle as an Event-type signal.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "edu_wpi_first_util_WPIUtilJNI.h"
|
||||
#include "wpi/PortForwarder.h"
|
||||
#include "wpi/Synchronization.h"
|
||||
#include "wpi/jni_util.h"
|
||||
#include "wpi/timestamp.h"
|
||||
|
||||
@@ -14,6 +15,8 @@ using namespace wpi::java;
|
||||
static bool mockTimeEnabled = false;
|
||||
static uint64_t mockNow = 0;
|
||||
|
||||
static JException interruptedEx;
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
@@ -22,10 +25,21 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
interruptedEx = JException(env, "java/lang/InterruptedException");
|
||||
if (!interruptedEx) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {}
|
||||
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
return;
|
||||
}
|
||||
interruptedEx.free(env);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
@@ -94,4 +108,169 @@ Java_edu_wpi_first_util_WPIUtilJNI_removePortForwarder
|
||||
wpi::PortForwarder::GetInstance().Remove(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: createEvent
|
||||
* Signature: (ZZ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_createEvent
|
||||
(JNIEnv*, jclass, jboolean manualReset, jboolean initialState)
|
||||
{
|
||||
return wpi::CreateEvent(manualReset, initialState);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: destroyEvent
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_destroyEvent
|
||||
(JNIEnv*, jclass, jint eventHandle)
|
||||
{
|
||||
wpi::DestroyEvent(eventHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: setEvent
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_setEvent
|
||||
(JNIEnv*, jclass, jint eventHandle)
|
||||
{
|
||||
wpi::SetEvent(eventHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: resetEvent
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_resetEvent
|
||||
(JNIEnv*, jclass, jint eventHandle)
|
||||
{
|
||||
wpi::ResetEvent(eventHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: createSemaphore
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_createSemaphore
|
||||
(JNIEnv*, jclass, jint initialCount, jint maximumCount)
|
||||
{
|
||||
return wpi::CreateSemaphore(initialCount, maximumCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: destroySemaphore
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_destroySemaphore
|
||||
(JNIEnv*, jclass, jint semHandle)
|
||||
{
|
||||
wpi::DestroySemaphore(semHandle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: releaseSemaphore
|
||||
* Signature: (II)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_releaseSemaphore
|
||||
(JNIEnv*, jclass, jint semHandle, jint releaseCount)
|
||||
{
|
||||
return wpi::ReleaseSemaphore(semHandle, releaseCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: waitForObject
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_waitForObject
|
||||
(JNIEnv* env, jclass, jint handle)
|
||||
{
|
||||
if (!wpi::WaitForObject(handle)) {
|
||||
interruptedEx.Throw(env, "WaitForObject interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: waitForObjectTimeout
|
||||
* Signature: (ID)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_waitForObjectTimeout
|
||||
(JNIEnv* env, jclass, jint handle, jdouble timeout)
|
||||
{
|
||||
bool timedOut;
|
||||
if (!wpi::WaitForObject(handle, timeout, &timedOut) && !timedOut) {
|
||||
interruptedEx.Throw(env, "WaitForObject interrupted");
|
||||
return false;
|
||||
}
|
||||
return timedOut;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: waitForObjects
|
||||
* Signature: ([I)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_waitForObjects
|
||||
(JNIEnv* env, jclass, jintArray handles)
|
||||
{
|
||||
JIntArrayRef handlesArr{env, handles};
|
||||
wpi::SmallVector<WPI_Handle, 8> signaledBuf;
|
||||
signaledBuf.resize(handlesArr.size());
|
||||
wpi::span<const WPI_Handle> handlesArr2{
|
||||
reinterpret_cast<const WPI_Handle*>(handlesArr.array().data()),
|
||||
handlesArr.size()};
|
||||
|
||||
auto signaled = wpi::WaitForObjects(handlesArr2, signaledBuf);
|
||||
if (signaled.empty()) {
|
||||
interruptedEx.Throw(env, "WaitForObjects interrupted");
|
||||
return nullptr;
|
||||
}
|
||||
return MakeJIntArray(env, signaled);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_util_WPIUtilJNI
|
||||
* Method: waitForObjectsTimeout
|
||||
* Signature: ([ID)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL
|
||||
Java_edu_wpi_first_util_WPIUtilJNI_waitForObjectsTimeout
|
||||
(JNIEnv* env, jclass, jintArray handles, jdouble timeout)
|
||||
{
|
||||
JIntArrayRef handlesArr{env, handles};
|
||||
wpi::SmallVector<WPI_Handle, 8> signaledBuf;
|
||||
signaledBuf.resize(handlesArr.size());
|
||||
wpi::span<const WPI_Handle> handlesArr2{
|
||||
reinterpret_cast<const WPI_Handle*>(handlesArr.array().data()),
|
||||
handlesArr.size()};
|
||||
|
||||
bool timedOut;
|
||||
auto signaled =
|
||||
wpi::WaitForObjects(handlesArr2, signaledBuf, timeout, &timedOut);
|
||||
if (signaled.empty() && !timedOut) {
|
||||
interruptedEx.Throw(env, "WaitForObjects interrupted");
|
||||
return nullptr;
|
||||
}
|
||||
return MakeJIntArray(env, signaled);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user