using System; using System.Threading; namespace ScreenConnect; public static class LockExtensions { public struct ReaderLockReleaser(ReaderWriterLock syncLock) : IDisposable { private ReaderWriterLock syncLock = syncLock; public void Dispose() { syncLock.ReleaseReaderLock(); } } public struct WriterLockReleaser(ReaderWriterLock syncLock) : IDisposable { private ReaderWriterLock syncLock = syncLock; public void Dispose() { syncLock.ReleaseWriterLock(); } } public static T WithLock(object syncLock, Func func) { lock (syncLock) { return func(); } } public static bool WithCheckedLock(Func getLockFunc, Func checker, Proc lockedProc) { if (checker()) { using (getLockFunc()) { if (checker()) { lockedProc(); return true; } } } return false; } public static ReaderLockReleaser ReaderLock(this ReaderWriterLock syncLock) { syncLock.AcquireReaderLock(-1); return new ReaderLockReleaser(syncLock); } public static WriterLockReleaser WriterLock(this ReaderWriterLock syncLock) { syncLock.AcquireWriterLock(-1); return new WriterLockReleaser(syncLock); } public static T WithReaderLockAndIfDefaultThenWriterLock(this ReaderWriterLock syncLock, Func funcWithWriterLockFlag) { T val = syncLock.WithReaderLock(() => funcWithWriterLockFlag(arg1: false)); if (val.EqualsDefault()) { return syncLock.WithWriterLock(() => funcWithWriterLockFlag(arg1: true)); } return val; } public static T WithReaderLock(this ReaderWriterLock syncLock, Func func) { using (syncLock.ReaderLock()) { return func(); } } public static void WithReaderLock(this ReaderWriterLock syncLock, Proc proc) { using (syncLock.ReaderLock()) { proc(); } } public static T WithWriterLock(this ReaderWriterLock syncLock, Func func) { using (syncLock.WriterLock()) { return func(); } } public static void WithWriterLock(this ReaderWriterLock syncLock, Proc proc) { using (syncLock.WriterLock()) { proc(); } } public static bool WithCheckedWriterLock(this ReaderWriterLock syncLock, Func checker, Proc lockedProc) { return WithCheckedLock(() => syncLock.WriterLock(), checker, lockedProc); } }