private void ResetState() { step = -1; myStream = null; bs.ResetSelf(); pos = 0; }
private void Dequeue(BytesSegment bs, int len) { Queue.CopyTo(bs, len); Queue.SubSelf(len); if (Queue.Len == 0) { Queue.ResetSelf(); } }
private AwaitableWrapper <BytesSegment> ReadNBAsyncRWrapper(int maxSize) { if (_nb_ra == null) { _nb_ra = new ReusableAwaiter <BytesSegment>(); } else { _nb_ra.Reset(); } var bs = BufferPool.GlobalGetBs(maxSize); var awaiter = BaseStream.ReadAsyncR(bs); if (awaiter.IsCompleted) { _nb_ra.SetResult(bs.Sub(0, awaiter.GetResult())); } else { _nb_bs = bs; if (_nb_continuation == null) { _nb_continuation = () => { var _bs = _nb_bs; var _awaiter = _nb_awaiter; _nb_bs.ResetSelf(); _nb_awaiter = default(AwaitableWrapper <int>); int r; try { r = _awaiter.GetResult(); } catch (Exception e) { _nb_ra.SetException(e); return; } _nb_ra.SetResult(_bs.Sub(0, r)); } } ; _nb_awaiter = awaiter; awaiter.OnCompleted(_nb_continuation); } return(new AwaitableWrapper <BytesSegment>(_nb_ra)); }
public async Task Copy(int bs, bool shutdown) { if (WhenCanRead != null) { await WhenCanRead; } IMsgStream msgStream = (From as MsgStreamToMyStream)?.MsgStream; if (bs == -1) { bs = defaultBufferSize; } Naive.HttpSvr.BytesSegment buf; Msg lastMsg = new Msg(); if (msgStream != null || (From is IMyStreamNoBuffer && !TryReadSync)) { buf = new BytesSegment(); } else { buf = BufferPool.GlobalGet(bs); } try { int syncCounter = 0; while (true) { BytesSegment tempBuf = new BytesSegment(); if (syncCounter > 64) { syncCounter = 0; await Task.Yield(); } // read: int read; if (msgStream != null) { // no buffer preallocated for IMsgStream var msg = await msgStream.RecvMsgR(null).SyncCounter(ref syncCounter); lastMsg = msg; if (msg.IsEOF) { read = 0; } else { read = msg.Data.tlen; if (msg.Data.nextNode == null) { buf = new BytesSegment(msg.Data); } else { buf = msg.Data.GetBytes(); } } } else if (TryReadSync && From is IMyStreamSync fromSync) { read = fromSync.Read(buf); } else if (From is IMyStreamNoBuffer nb) { tempBuf = await nb.ReadNBAsyncR(bs).SyncCounter(ref syncCounter); buf = tempBuf; read = tempBuf.Len; } else { read = await From.ReadAsyncR(buf).SyncCounter(ref syncCounter); } // handle shutdown: if (read == 0) { VerboseLogger?.debugForce($"SHUTDOWN: {From} -> {To}"); if (shutdown && !To.State.HasShutdown) { await To.Shutdown(SocketShutdown.Send).CAF(); } break; } ProcessPayload(buf.Sub(0, read)); Progress += read; CounterR?.Add(read); // write: if (TryWriteSync && To is IMyStreamSync toSync) { toSync.Write(new BytesSegment(buf.Bytes, buf.Offset, read)); } else { await To.WriteAsyncR(new BytesSegment(buf.Bytes, buf.Offset, read)).SyncCounter(ref syncCounter); } CounterW?.Add(read); // recycle buffer if possible: if (lastMsg.Data != null) { lastMsg.TryRecycle(); buf.ResetSelf(); } if (tempBuf.Bytes != null) { BufferPool.GlobalPut(tempBuf.Bytes); tempBuf.ResetSelf(); buf.ResetSelf(); } } } finally { VerboseLogger?.debugForce($"STOPPED: {From} -> {To}"); //if (buf.Bytes != null) { // BufferPool.GlobalPut(buf.Bytes); //} } }