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:
Thad House
2018-06-03 08:43:48 -07:00
committed by Peter Johnson
parent 6aebba5452
commit 8eafe7f325
10 changed files with 42 additions and 36 deletions

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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});
}
/*

View File

@@ -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) {

View File

@@ -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) {