private void CompleteRead(IoUringConnectionContext context, int result) { var readHandles = context.ReadHandles; for (int i = 0; i < readHandles.Length; i++) { readHandles[i].Dispose(); } if (result > 0) { Debug.WriteLine($"Read {result} from {(int)context.Socket}"); context.Input.Advance(result); FlushRead(context); } else if (result < 0) { if (-result == ECONNRESET) { context.DisposeAsync(); } else if (-result != EAGAIN && -result != EWOULDBLOCK && -result != EINTR) { throw new ErrnoException(-result); } Debug.WriteLine($"Read completed with EAGAIN from {(int)context.Socket}"); } else { context.DisposeAsync(); } }
private void CompleteRead(IoUringConnectionContext context, int result) { if (result > 0) { Debug.WriteLine($"Read {result} bytes from {(int)context.Socket}"); context.Input.Advance(result); FlushRead(context); } else if (result < 0) { if (-result == ECONNRESET) { context.DisposeAsync(); } else if (-result != EAGAIN && -result != EWOULDBLOCK && -result != EINTR) { throw new ErrnoException(-result); } Debug.WriteLine("Read for nothing"); } else { // TODO: handle connection closed } }
private void CompleteWrite(IoUringConnectionContext context, int result) { var writeHandles = context.WriteHandles; for (int i = 0; i < writeHandles.Length; i++) { writeHandles[i].Dispose(); } var lastWrite = context.LastWrite; if (result >= 0) { SequencePosition end; if (result == 0) { Debug.WriteLine($"Wrote {result} bytes to {(int)context.Socket}"); end = lastWrite.Start; } else if (lastWrite.Length == result) { Debug.WriteLine($"Wrote all {result} bytes to {(int)context.Socket}"); end = lastWrite.End; } else { Debug.WriteLine($"Wrote some {result} bytes to {(int)context.Socket}"); end = lastWrite.GetPosition(result); } context.Output.AdvanceTo(end); ReadFromApp(context); } else if (result < 0) { if (-result == ECONNRESET || -result == EPIPE) { context.DisposeAsync(); } else if (-result == EAGAIN || -result == EWOULDBLOCK || -result == EINTR) { Debug.WriteLine("Wrote for nothing"); context.Output.AdvanceTo(lastWrite.Start); ReadFromApp(context); } else { throw new ErrnoException(-result); } } }
private void Write(IoUringConnectionContext context) { var result = context.ReadResult.Result; var buffer = result.Buffer; var socket = context.Socket; if ((buffer.IsEmpty && result.IsCompleted) || result.IsCanceled) { context.DisposeAsync(); _connections.TryRemove(socket, out _); return; } var writeHandles = context.WriteHandles; var writeVecs = context.WriteVecs; int ctr = 0; foreach (var memory in buffer) { var handle = memory.Pin(); writeVecs[ctr].iov_base = handle.Pointer; writeVecs[ctr].iov_len = memory.Length; writeHandles[ctr] = handle; ctr++; if (ctr == IoUringConnectionContext.WriteIOVecCount) { break; } } context.LastWrite = buffer; Debug.WriteLine($"Adding write on {(int)socket}"); Span <Submission> submissions = stackalloc Submission[2]; _ring.AcquireSubmissions(submissions); submissions[0].PreparePollAdd(socket, (ushort)POLLOUT, options: SubmissionOption.Link); _ring.Release(submissions[0]); submissions[1].PrepareWriteV(socket, writeVecs, ctr, 0, 0, Mask(socket, WriteMask)); _ring.Release(submissions[1]); }
private unsafe void Write(IoUringConnectionContext context) { var result = context.ReadResult.Result; var socket = context.Socket; if (result.IsCanceled || result.IsCompleted) { context.DisposeAsync(); _connections.Remove(socket); socket.Close(); return; } var writeHandles = context.WriteHandles; var writeVecs = context.WriteVecs; var buffer = result.Buffer; int ctr = 0; foreach (var memory in buffer) { var handle = memory.Pin(); writeVecs[ctr].iov_base = handle.Pointer; writeVecs[ctr].iov_len = memory.Length; writeHandles[ctr] = handle; ctr++; if (ctr == IoUringConnectionContext.WriteIOVecCount) { break; } } context.LastWrite = buffer; Debug.WriteLine($"Adding write on {(int)socket}"); _ring.PrepareWriteV(socket, writeVecs, ctr, 0, 0, Mask(socket, WriteMask)); }