public async Task <byte[]> GetRpcResultAsync(long callUid, CancellationToken token) { IDisposable monitor = null; try { monitor = await m_monitor.EnterAsync(token).ConfigureAwait(false); if (!m_blockingRpcCalls.Add(callUid)) { return(null); } for (;;) { var pair = new ImmutablePair <uint, uint>((uint)callUid >> 16, (uint)callUid & 0xffff); byte[] str; if (!m_rpcResults.TryGetValue(pair, out str)) { if (m_terminating) { m_blockingRpcCalls.Remove(callUid); return(null); } await m_monitor.WaitAsync(token).ConfigureAwait(false); if (token.IsCancellationRequested) { m_blockingRpcCalls.Remove(callUid); return(null); } if (m_terminating) { m_blockingRpcCalls.Remove(callUid); return(null); } continue; } byte[] result = new byte[str.Length]; Array.Copy(str, result, result.Length); m_blockingRpcCalls.Remove(callUid); return(result); } } catch (OperationCanceledException) { // Operation canceled. Return null. return(null); } finally { monitor?.Dispose(); } }
public void PostRpcResponse(long rpcId, long callId, params byte[] result) { SendMsgFunc func; var pair = new ImmutablePair <uint, uint>((uint)rpcId, (uint)callId); if (!m_responseMap.TryGetValue(pair, out func)) { Warning("posting PRC response to nonexistent call (or duplicate response)"); return; } func(Message.RpcResponse((uint)rpcId, (uint)callId, result)); m_responseMap.Remove(pair); }
public bool GetRpcResult(bool blocking, long callUid, TimeSpan timeout, out byte[] result) { IDisposable monitor = null; try { monitor = m_monitor.Enter(); if (!m_blockingRpcCalls.Add(callUid)) { result = null; return(false); } for (;;) { var pair = new ImmutablePair <uint, uint>((uint)callUid >> 16, (uint)callUid & 0xffff); byte[] str; if (!m_rpcResults.TryGetValue(pair, out str)) { if (!blocking || m_terminating) { result = null; m_blockingRpcCalls.Remove(callUid); return(false); } CancellationTokenSource source = new CancellationTokenSource(); var task = m_monitor.WaitAsync(source.Token); bool success = task.Wait(timeout); if (!success || m_terminating) { source.Cancel(); m_blockingRpcCalls.Remove(callUid); result = null; return(false); } continue; } result = new byte[str.Length]; Array.Copy(str, result, result.Length); m_blockingRpcCalls.Remove(callUid); return(true); } } finally { monitor?.Dispose(); } }
public bool Equals(ImmutablePair <T, T2> other) { return(EqualityComparer <T> .Default.Equals(First, other.First) && EqualityComparer <T2> .Default.Equals(Second, other.Second)); }