C# extension methods for the ReaderWriterLockSlim class.

using System;
using System.Threading;

namespace Baseline
{
    public static class ReaderWriterLockSlimExtensions
    {
        public static void Write(this ReaderWriterLockSlim lock, Action action)
        {
            lock.EnterWriteLock();
            try
            {
                action();
            }
            finally
            {
                lock.ExitWriteLock();
            }
        }

        public static T Read<T>(this ReaderWriterLockSlim lock, Func<T> func)
        {
            lock.EnterReadLock();
            try
            {
                return func();
            }
            finally
            {
                lock.ExitReadLock();
            }
        }

        public static void MaybeWrite(this ReaderWriterLockSlim lock, Action action)
        {
            try
            {
                lock.EnterUpgradeableReadLock();
                action();
            }
            finally
            {
                lock.ExitUpgradeableReadLock();
            }
        }

        public static T MaybeWrite<T>(this ReaderWriterLockSlim lock, Func<T> answer, Func<bool> missingTest,
                                      Action write)
        {
            try
            {
                lock.EnterUpgradeableReadLock();
                if (missingTest())
                {
                    lock.Write(() =>
                    {
                        if (missingTest())
                        {
                            write();
                        }
                    });
                }

                return answer();
            }
            finally
            {
                lock.ExitUpgradeableReadLock();
            }
        }
    }
}