mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Solve some safety issues with RPCs (#1127)
Java would never properly dispose, and C++'s were easy to respond after disposing. We now return a bool if the call was successful or not.
This commit is contained in:
committed by
Peter Johnson
parent
6aebba5452
commit
8eafe7f325
@@ -35,14 +35,15 @@ void RpcServer::ProcessRpc(unsigned int local_id, unsigned int call_uid,
|
||||
send_response);
|
||||
}
|
||||
|
||||
void RpcServer::PostRpcResponse(unsigned int local_id, unsigned int call_uid,
|
||||
bool RpcServer::PostRpcResponse(unsigned int local_id, unsigned int call_uid,
|
||||
wpi::StringRef result) {
|
||||
auto thr = GetThread();
|
||||
auto i = thr->m_response_map.find(impl::RpcIdPair{local_id, call_uid});
|
||||
if (i == thr->m_response_map.end()) {
|
||||
WARNING("posting RPC response to nonexistent call (or duplicate response)");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
(i->getSecond())(result);
|
||||
thr->m_response_map.erase(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class RpcServer : public IRpcServer,
|
||||
SendResponseFunc send_response,
|
||||
unsigned int rpc_uid) override;
|
||||
|
||||
void PostRpcResponse(unsigned int local_id, unsigned int call_uid,
|
||||
bool PostRpcResponse(unsigned int local_id, unsigned int call_uid,
|
||||
wpi::StringRef result);
|
||||
|
||||
private:
|
||||
|
||||
@@ -1255,17 +1255,17 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_waitForRpcCallQueue
|
||||
/*
|
||||
* Class: edu_wpi_first_networktables_NetworkTablesJNI
|
||||
* Method: postRpcResponse
|
||||
* Signature: (II[B)V
|
||||
* Signature: (II[B)Z
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_edu_wpi_first_networktables_NetworkTablesJNI_postRpcResponse
|
||||
(JNIEnv* env, jclass, jint entry, jint call, jbyteArray result)
|
||||
{
|
||||
if (!result) {
|
||||
nullPointerEx.Throw(env, "result cannot be null");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
nt::PostRpcResponse(entry, call, JByteArrayRef{env, result});
|
||||
return nt::PostRpcResponse(entry, call, JByteArrayRef{env, result});
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -431,9 +431,9 @@ NT_Bool NT_WaitForRpcCallQueue(NT_Inst inst, double timeout) {
|
||||
return nt::WaitForRpcCallQueue(inst, timeout);
|
||||
}
|
||||
|
||||
void NT_PostRpcResponse(NT_Entry entry, NT_RpcCall call, const char* result,
|
||||
size_t result_len) {
|
||||
nt::PostRpcResponse(entry, call, StringRef(result, result_len));
|
||||
NT_Bool NT_PostRpcResponse(NT_Entry entry, NT_RpcCall call, const char* result,
|
||||
size_t result_len) {
|
||||
return nt::PostRpcResponse(entry, call, StringRef(result, result_len));
|
||||
}
|
||||
|
||||
NT_RpcCall NT_CallRpc(NT_Entry entry, const char* params, size_t params_len) {
|
||||
|
||||
@@ -560,18 +560,18 @@ bool WaitForRpcCallQueue(NT_Inst inst, double timeout) {
|
||||
return ii->rpc_server.WaitForQueue(timeout);
|
||||
}
|
||||
|
||||
void PostRpcResponse(NT_Entry entry, NT_RpcCall call, StringRef result) {
|
||||
bool PostRpcResponse(NT_Entry entry, NT_RpcCall call, StringRef result) {
|
||||
Handle handle{entry};
|
||||
int id = handle.GetTypedIndex(Handle::kEntry);
|
||||
auto ii = InstanceImpl::Get(handle.GetInst());
|
||||
if (id < 0 || !ii) return;
|
||||
if (id < 0 || !ii) return false;
|
||||
|
||||
Handle chandle{call};
|
||||
int call_uid = chandle.GetTypedIndex(Handle::kRpcCall);
|
||||
if (call_uid < 0) return;
|
||||
if (handle.GetInst() != chandle.GetInst()) return;
|
||||
if (call_uid < 0) return false;
|
||||
if (handle.GetInst() != chandle.GetInst()) return false;
|
||||
|
||||
ii->rpc_server.PostRpcResponse(id, call_uid, result);
|
||||
return ii->rpc_server.PostRpcResponse(id, call_uid, result);
|
||||
}
|
||||
|
||||
NT_RpcCall CallRpc(NT_Entry entry, StringRef params) {
|
||||
|
||||
Reference in New Issue
Block a user