using System; using System.Threading; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Generic; namespace DuckEmulator.Security { /// /// Implements a thread-safe list with support for multiple readers and one writer /// /// Values /// public sealed class SecurityList : IList { private readonly List _inner; private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); public SecurityList() { _inner = new List(); } public SecurityList(int capacity) { _inner = new List(capacity); } public SecurityList(SecurityList original) { _inner = new List(original); } public void Dispose() { _lock.Dispose(); } public int Count { get { using (RWLSExtension.ReadLock(_lock)) { return _inner.Count; } } } public bool IsReadOnly { get { return false; } } public TKey this[int index] { get { using (RWLSExtension.ReadLock(_lock)) { return _inner[index]; } } set { using (RWLSExtension.WriteLock(_lock)) { _inner[index] = value; } } } IEnumerator IEnumerable.GetEnumerator() { using (RWLSExtension.ReadLock(_lock)) { return new List(_inner).GetEnumerator(); } } public void Add(TKey item) { using (RWLSExtension.WriteLock(_lock)) { _inner.Add(item); } } public void Clear() { using (RWLSExtension.WriteLock(_lock)) { _inner.Clear(); } } public bool Contains(TKey item) { using (RWLSExtension.ReadLock(_lock)) { return _inner.Contains(item); } } public void CopyTo(TKey[] array, int arrayIndex) { using (RWLSExtension.ReadLock(_lock)) { _inner.CopyTo(array, arrayIndex); } } public bool Remove(TKey item) { using (RWLSExtension.WriteLock(_lock)) { return _inner.Remove(item); } } public IEnumerator GetEnumerator() { using (RWLSExtension.ReadLock(_lock)) { return new List(_inner).GetEnumerator(); } } public int IndexOf(TKey item) { using (RWLSExtension.ReadLock(_lock)) { return _inner.IndexOf(item); } } public void Insert(int index, TKey item) { using (RWLSExtension.WriteLock(_lock)) { _inner.Insert(index, item); } } public void RemoveAt(int index) { using (RWLSExtension.WriteLock(_lock)) { _inner.RemoveAt(index); } } public ReadOnlyCollection AsReadOnly() { using (RWLSExtension.ReadLock(_lock)) { return new ReadOnlyCollection(this); } } public void ForEach(Action action) { using (RWLSExtension.WriteLock(_lock)) { foreach (var item in _inner) { action(item); } } } public bool Exists(Predicate match) { using (RWLSExtension.ReadLock(_lock)) { foreach (var item in _inner) { if (match(item)) { return true; } } } return false; } } }