Skip to content

Ergonomics could be better #1

@matthew-a-thomas

Description

@matthew-a-thomas

As of 0.1.9, guarded side effects are allowed by any await within the guarded section (if the lock has been reentered), not just by the await on the task that reentered the lock.

For example, this program throws an exception when the casual observer might expect it to work:

namespace Example;

using System.Threading.Tasks;
using ReentrantAsyncLock;
using Xunit;

class Program
{
    static async Task Main()
    {
	var gate = new ReentrantAsyncLock();
	var state = 0;
	async Task ChangeGuardedStateAsync()
	{
	    await using (await gate.LockAsync(default))
            {
                state++;
            }
        }
        await using (await gate.LockAsync(default))
        {
            var task = ChangeGuardedStateAsync();
            var stateBefore = state;
            await Task.Yield(); // Seemingly unrelated
            Assert.Equal(stateBefore, state); // ...but it allows side effects on the guarded state (this line throws)
            await task;
        }
    }
}

.NET Fiddle: https://dotnetfiddle.net/FzQ1qR

Thanks to Max Fedotov for patiently explaining this to me.

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions