#region COPYRIGHT
//
//     THIS IS GENERATED BY TEMPLATE
//     
//     AUTHOR  :     ROYE
//     DATE       :     2010
//
//     COPYRIGHT (C) 2010, TIANXIAHOTEL TECHNOLOGIES CO., LTD. ALL RIGHTS RESERVED.
//
#endregion

using System;
using System.Collections.Generic;
using System.Threading;

namespace System.Reflection.Emit
{
    internal class DelegateCache
    {
        private readonly Dictionary<CallInfo_, Delegate> _Map = new Dictionary<CallInfo_, Delegate>();
        private readonly ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim();

        public Delegate GetDelegate(CallInfo_ callInfo, Func<Delegate> func)
        {
            Delegate action;
            bool exist;
            readerWriterLock.EnterReadLock();
            try
            {
                exist = _Map.TryGetValue(callInfo, out action);
            }
            finally
            {
                readerWriterLock.ExitReadLock();
            }

            if (exist) return action;

            readerWriterLock.EnterWriteLock();
            try
            {
                if (!_Map.ContainsKey(callInfo))
                {
                    action = func();
                    _Map.Add(callInfo, action);
                }
            }
            finally
            {
                readerWriterLock.ExitWriteLock();
            }
            return action;
        }
    }
}
