public async Task PassthroughIfAllFlushesAreAwaited()
        {
            using (var slabPool = new SlabMemoryPool())
                using (var diagnosticPool = new DiagnosticMemoryPool(slabPool))
                {
                    var pipeWriterFlushTcsArray = new[] {
                        new TaskCompletionSource <FlushResult>(TaskCreationOptions.RunContinuationsAsynchronously),
                        new TaskCompletionSource <FlushResult>(TaskCreationOptions.RunContinuationsAsynchronously),
                    };

                    var sync                 = new object();
                    var mockPipeWriter       = new MockPipeWriter(pipeWriterFlushTcsArray);
                    var concurrentPipeWriter = new ConcurrentPipeWriter(mockPipeWriter, diagnosticPool, sync);

                    ValueTask <FlushResult> flushTask;

                    lock (sync)
                    {
                        var memory = concurrentPipeWriter.GetMemory();
                        Assert.Equal(1, mockPipeWriter.GetMemoryCallCount);

                        concurrentPipeWriter.Advance(memory.Length);
                        Assert.Equal(1, mockPipeWriter.AdvanceCallCount);

                        flushTask = concurrentPipeWriter.FlushAsync();
                        Assert.Equal(1, mockPipeWriter.FlushCallCount);

                        pipeWriterFlushTcsArray[0].SetResult(default);
예제 #2
0
        public TransportThread(IoUringOptions options)
        {
            int res = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);

            if (res == -1)
            {
                throw new ErrnoException(errno);
            }
            _eventfd = res;

            // Pin buffer for eventfd reads via io_uring
            byte[] bytes = new byte[8];
            _eventfdBytes = GCHandle.Alloc(bytes, GCHandleType.Pinned);

            // Pin iovec used for eventfd reads via io_uring
            var eventfdIoVec = new iovec
            {
                iov_base = (void *)_eventfdBytes.AddrOfPinnedObject(),
                iov_len  = bytes.Length
            };

            _eventfdIoVecHandle = GCHandle.Alloc(eventfdIoVec, GCHandleType.Pinned);
            _eventfdIoVec       = (iovec *)_eventfdIoVecHandle.AddrOfPinnedObject();

            var memoryPool = new SlabMemoryPool();

            _threadContext = new TransportThreadContext(options, memoryPool, _eventfd, s => Read(s), s => Write(s));
            _maxBufferSize = memoryPool.MaxBufferSize;
        }