csharp/0x0ade/CelesteNet/CelesteNet.Shared/RWLock.cs

RWLock.cs
using Celeste.Mod.CelesteNet.DataTypes;
using Celeste.Mod.Helpers;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Codeastysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Celeste.Mod.CelesteNet {
    public clast RWLock : IDisposable {

        public readonly ReaderWriterLockSlim Inner = new(LockRecursionPolicy.SupportsRecursion);
        private readonly RLock _R;
        private readonly RULock _RU;
        private readonly WLock _W;

        public RWLock() {
            _R = new(Inner);
            _RU = new(Inner);
            _W = new(Inner);
        }

        public RLock R() => _R.Start();
        public RULock RU() => _RU.Start();
        public WLock W() => _W.Start();

        public void Dispose() {
            Inner.Dispose();
        }

        public clast RLock : IDisposable {
            public readonly ReaderWriterLockSlim Inner;

            public RLock(ReaderWriterLockSlim inner) {
                Inner = inner;
            }

            public RLock Start() {
                Inner.EnterReadLock();
                return this;
            }

            public void Dispose() {
                Inner.ExitReadLock();
            }
        }

        public clast RULock : IDisposable {
            public readonly ReaderWriterLockSlim Inner;

            public RULock(ReaderWriterLockSlim inner) {
                Inner = inner;
            }

            public RULock Start() {
                Inner.EnterUpgradeableReadLock();
                return this;
            }

            public void Dispose() {
                Inner.ExitUpgradeableReadLock();
            }
        }

        public clast WLock : IDisposable {
            public readonly ReaderWriterLockSlim Inner;

            public WLock(ReaderWriterLockSlim inner) {
                Inner = inner;
            }

            public WLock Start() {
                Inner.EnterWriteLock();
                return this;
            }

            public void Dispose() {
                Inner.ExitWriteLock();
            }
        }

    }
}