/// <deprecated> /// Not used. For reference only. /// </deprecated> private async void StartPolling1() { while (true) { var readResult = await pipeReader.ReadAsync().ConfigureAwait(false); ReadOnlySequence <byte> buffer = readResult.Buffer; SequencePosition? position = buffer.Start; var remainingBytes = buffer.Length; var writeResult = (byte)0; while (remainingBytes > 0) { while (localStackByteCount == 0) { await _tun.executeLwipTask(() => _socket.Output()); await localStackBufLock.WaitAsync().ConfigureAwait(false); } var bytesToWriteCount = Math.Min(remainingBytes, localStackByteCount); var chunk = buffer.Slice(position.Value, bytesToWriteCount); var arr = chunk.ToArray(); var more = remainingBytes != bytesToWriteCount; writeResult = await _tun.executeLwipTask(() => _socket.Send(arr, more)); if (writeResult != 0) { OnError?.Invoke(this, writeResult); pipeReader.Complete(); return; } remainingBytes -= bytesToWriteCount; position = buffer.GetPosition(bytesToWriteCount, position.Value); Interlocked.Add(ref localStackByteCount, (int)-bytesToWriteCount); } pipeReader.AdvanceTo(position.Value, position.Value); await _tun.executeLwipTask(() => _socket.Output()); if (readResult.IsCanceled || readResult.IsCompleted || writeResult != 0) { break; } } pipeReader.Complete(); await _tun.executeLwipTask(() => _socket.Close()); Debug.WriteLine($"{TcpSocket.ConnectionCount()} connections now"); LocalDisconnected = true; OnFinished(this); CheckShutdown(); }
private async ValueTask <bool> PushOne() { var readResult = await inboundReader.ReadAsync(pushCancelSource.Token).ConfigureAwait(false); var buffer = readResult.Buffer; byte writeResult = 0; var start = buffer.Start; // A buffer may consist of several Memory<byte> chunks, // read one of them at a time. // Note that a chunk may be large, thus must be splitted into smaller chunks. while (buffer.TryGet(ref start, out var remainingChunk)) { while (remainingChunk.Length > 0) { // Wait until there is enough space in the stack while (localStackAvailableByteCount <= 1600) { await localStackBufLock.WaitAsync(pushCancelSource.Token).ConfigureAwait(false); } var len = Math.Min(localStackAvailableByteCount, remainingChunk.Length); var chunk = remainingChunk.Slice(0, len); remainingChunk = remainingChunk.Slice(len); var more = true;// remainingChunk.Length != 0 || !start.Equals(buffer.End); using (var dataHandle = chunk.Pin()) { writeResult = await SendToSocket(dataHandle, (ushort)chunk.Length, more).ConfigureAwait(false); while (writeResult == 255) { if (!await(localStackBufLock?.WaitAsync(10000, pushCancelSource.Token).ConfigureAwait(false) ?? Task.FromResult(false).ConfigureAwait(false))) { DebugLogger.Log("Local write timeout"); break; } writeResult = await SendToSocket(dataHandle, (ushort)chunk.Length, more).ConfigureAwait(false); } } if (writeResult != 0) { DebugLogger.Log("Error from writing to local socket:" + writeResult.ToString()); // TODO: distinguish write error with general socket error Socket_SocketError(_socket, writeResult); return(false); } Interlocked.Add(ref localStackAvailableByteCount, -chunk.Length); Interlocked.Add(ref localPendingByteCount, chunk.Length); await _tun.executeLwipTask(() => _socket.Output()); } } inboundReader.AdvanceTo(buffer.End); //await _tun.executeLwipTask(() => _socket.Output()); if (readResult.IsCanceled || readResult.IsCompleted || writeResult != 0 || pushCancelSource.IsCancellationRequested) { return(false); } return(true); }