internal async Task PingAsync(int ackId, DataLinkShareData data, CancellationToken cancellationToken) { bool isHealthy; try { await SendRawWithAckAsync(ackId, data, cancellationToken); isHealthy = true; } catch (OperationCanceledException) { isHealthy = false; } if (IsHealthy != isHealthy) { IsHealthy = isHealthy; _handler.OnHealthyChanged(_dlc, this); } }
internal async Task <bool> SendRawWithAckAsync(int?ackId, DataLinkShareData data, CancellationToken cancellationToken) { if (ackId == null) { await Write(data); return(true); } var tcs = new TaskCompletionSource <bool>(); cancellationToken.Register(s => ((TaskCompletionSource <bool>)s).TrySetCanceled(), tcs); _acks.TryAdd(ackId.Value, tcs); await Write(data); try { return(await tcs.Task); } finally { _acks.TryRemove(ackId.Value, out _); } }
private async ValueTask Write(DataLinkShareData data) { if (!_writeLock.Wait(0)) { Interlocked.Increment(ref _waitingForWriteLock); await _writeLock.WaitAsync(); Interlocked.Decrement(ref _waitingForWriteLock); } try { await _outPipe.Writer.WriteAsync(data.Head.Memory); if (!data.Body.IsEmpty) { await _outPipe.Writer.WriteAsync(data.Body); } } finally { data.Done(); _writeLock.Release(); } }
internal ValueTask SendRaw(DataLinkShareData data) { return(Write(data)); }