Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 4
0
        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]);
        }
Exemplo n.º 5
0
        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));
        }