mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
Fixes possible indefinite timeout on multiple RPC calls (#120)
Calculates timeout before the RPC call checks ever loop.
This commit is contained in:
committed by
Peter Johnson
parent
53d0789660
commit
9047c98e68
@@ -66,19 +66,19 @@ bool RpcServer::PollRpc(bool blocking, RpcCallInfo* call_info) {
|
||||
|
||||
bool RpcServer::PollRpc(bool blocking, double time_out, RpcCallInfo* call_info) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<int64_t, std::nano>(static_cast<int64_t>
|
||||
(time_out * 1e9));
|
||||
#else
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<double>(time_out);
|
||||
#endif
|
||||
while (m_poll_queue.empty()) {
|
||||
if (!blocking || m_terminating) return false;
|
||||
if (time_out < 0) {
|
||||
m_poll_cond.wait(lock);
|
||||
} else {
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<int64_t, std::nano>(static_cast<int64_t>
|
||||
(time_out * 1e9));
|
||||
#else
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<double>(time_out);
|
||||
#endif
|
||||
auto timed_out = m_poll_cond.wait_until(lock, timeout_time);
|
||||
if (timed_out == std::cv_status::timeout) {
|
||||
return false;
|
||||
|
||||
@@ -1417,6 +1417,14 @@ bool Storage::GetRpcResult(bool blocking, unsigned int call_uid, double time_out
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
// only allow one blocking call per rpc call uid
|
||||
if (!m_rpc_blocking_calls.insert(call_uid).second) return false;
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<int64_t, std::nano>(static_cast<int64_t>
|
||||
(time_out * 1e9));
|
||||
#else
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<double>(time_out);
|
||||
#endif
|
||||
for (;;) {
|
||||
auto i =
|
||||
m_rpc_results.find(std::make_pair(call_uid >> 16, call_uid & 0xffff));
|
||||
@@ -1428,14 +1436,6 @@ bool Storage::GetRpcResult(bool blocking, unsigned int call_uid, double time_out
|
||||
if (time_out < 0) {
|
||||
m_rpc_results_cond.wait(lock);
|
||||
} else {
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<int64_t, std::nano>(static_cast<int64_t>
|
||||
(time_out * 1e9));
|
||||
#else
|
||||
auto timeout_time = std::chrono::steady_clock::now() +
|
||||
std::chrono::duration<double>(time_out);
|
||||
#endif
|
||||
auto timed_out = m_rpc_results_cond.wait_until(lock, timeout_time);
|
||||
if (timed_out == std::cv_status::timeout) {
|
||||
m_rpc_blocking_calls.erase(call_uid);
|
||||
|
||||
Reference in New Issue
Block a user