AsyncEx icon indicating copy to clipboard operation
AsyncEx copied to clipboard

Deadlock with AsyncReaderWriterLock

Open blair-ahlquist opened this issue 3 years ago • 2 comments

The following code deadlocks:

        [Test]
        public async Task NitoMultipleReadThenWriteAsync()
        {
            AsyncReaderWriterLock asyncLock = new AsyncReaderWriterLock();

            void enterReadThenWrite()
            {
                using (asyncLock.ReaderLock()) { }
                using (asyncLock.WriterLock()) { }
            }

            await Task.WhenAll(Enumerable.Range(0, 100).Select(x => Task.Run(enterReadThenWrite)));
        }

blair-ahlquist avatar May 16 '22 16:05 blair-ahlquist

Hmm... I went back to this after encountering similar issues with code using SemaphoreSlim. The above code eventually completes after over a minute!

blair-ahlquist avatar May 18 '22 01:05 blair-ahlquist

I haven't had a chance to run this yet, but that is what I suspected.

This isn't a deadlock, but it is the result of thread pool exhaustion. All the AsyncEx primitives (as well as SemaphoreSlim) require a free thread pool thread to unlock, and if all the thread pool threads are busy waiting, this can cause extremely slow progress. The thread pool will (eventually) add another thread, which is then used either to block immediately (enterReadThenWrite), or used to unlock one of the primitives and then blocked immediately.

As such, this is a duplicate of #107, which I am planning to fix eventually, but haven't yet had time.

StephenCleary avatar May 18 '22 12:05 StephenCleary