/// <summary> /// Set up the cache. /// </summary> static DescriptionResolver() { _cachePadlock = new Padlock(); _cache = new ThreadShared<Dictionary<string, Dictionary<string, string>>>( new Dictionary<string, Dictionary<string, string>>(), _cachePadlock); }
public void Constructor_OtherPadlockNull() { Padlock p1 = new Padlock(); Padlock p2 = null; Padlock p3 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1, p2, p3); }
/// <summary> /// Creates a new ThreadShared resource. /// </summary> /// <param name="value"> /// The variable that is shared /// </param> /// <param name="firstMandatoryLock"> /// All ThreadShared must be protected by at least 1 Padlock /// </param> /// <param name="otherLocks"> /// All ThreadShared MAY be protected by a set of Padlocks, pass the /// other Padlocks that this resource is controlled by here. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if firstMandatoryLock is null /// </exception> public ThreadShared( T value, Padlock firstMandatoryLock, params Padlock[] otherLocks) : base(firstMandatoryLock, otherLocks) { _value = value; }
/// <summary> /// Called from a Padlock when the padlock is unlocked. /// </summary> /// <param name="plock"> /// The padlock that is attempting to end protection of this resource. /// </param> internal void EndProtection(Padlock plock) { lock (_internalStateLock) { EnsureLockIsAssociatedWithThisResource(plock); _associatedPadlocks[plock]--; } }
/// <summary> /// Called from a Padlock when the padlock is locked. /// </summary> /// <param name="plock"> /// The padlock that is attempting to start protection of this resource. /// </param> internal void StartProtection(Padlock plock) { lock (_internalStateLock) { EnsureLockIsAssociatedWithThisResource(plock); _associatedPadlocks[plock]++; } }
/// <summary> /// Ensures that the supplied Padlock is associated with this protected resource. /// </summary> /// <exception cref="System.ArgumentException"> /// Thrown if the supplied padlock is not associated with this resource. /// </exception> private void EnsureLockIsAssociatedWithThisResource(Padlock plock) { //MAKE SURE THAT _internalStateLock IS TAKEN BEFORE CALLING THIS METHOD if (!_associatedPadlocks.Keys.Contains(plock)) { throw new ArgumentException("This resource is not protected by this lock"); } }
public void Constructor_ConstructWithValueType() { Padlock p = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(10, p); using (p.Lock()) { Assert.AreEqual(i.Value, 10); } }
public void Constructor_ConstructWithReferenceType() { Padlock p = new Padlock(); //Uri is a random reference type; ThreadShared<Uri> i = new ThreadShared<Uri>(new Uri("http://example.com"), p); using (p.Lock()) { Assert.AreEqual(i.Value, new Uri("http://example.com")); } }
/// <summary> /// Creates a new ThreadShared resource /// </summary> /// <param name="firstMandatoryLock"> /// All ThreadShared resources MUST be associated with at least 1 lock /// </param> /// <param name="otherLocks"> /// Some resources need to be protected by more than 1 lock, specify /// all the other padlocks that protect this resource here. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if FirstMandatorLock is null /// </exception> protected BaseThreadShared(Padlock firstMandatoryLock, params Padlock[] otherLocks) { Insist.IsNotNull(firstMandatoryLock, "firstMandatoryLock"); Insist.AllItemsAreNotNull(otherLocks, "otherLocks"); _associatedPadlocks = new Dictionary<Padlock, int>(); _associatedPadlocks.Add(firstMandatoryLock, 0); foreach (Padlock currentPadlock in otherLocks) { _associatedPadlocks.Add(currentPadlock, 0); } //Register this ThreadShared resource with all of the associated Padlocks. foreach (Padlock currentPadlock in _associatedPadlocks.Keys) { currentPadlock.Register(this); } }
/// <summary> /// Creates a new ThreadShared resource /// </summary> /// <param name="firstMandatoryLock"> /// All ThreadShared resources MUST be associated with at least 1 lock /// </param> /// <param name="otherLocks"> /// Some resources need to be protected by more than 1 lock, specify /// all the other padlocks that protect this resource here. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if FirstMandatorLock is null /// </exception> protected BaseThreadShared(Padlock firstMandatoryLock, params Padlock[] otherLocks) { Insist.IsNotNull(firstMandatoryLock, "firstMandatoryLock"); Insist.AllItemsAreNotNull(otherLocks, "otherLocks"); _associatedPadlocks = new Dictionary <Padlock, int>(); _associatedPadlocks.Add(firstMandatoryLock, 0); foreach (Padlock currentPadlock in otherLocks) { _associatedPadlocks.Add(currentPadlock, 0); } //Register this ThreadShared resource with all of the associated Padlocks. foreach (Padlock currentPadlock in _associatedPadlocks.Keys) { currentPadlock.Register(this); } }
private void RecursiveFunction(int maxRecursionDepth, int currentDepth, Padlock p, ThreadShared<int> i) { if (currentDepth < maxRecursionDepth) { using (p.Lock()) { i.Value++; RecursiveFunction(maxRecursionDepth, ++currentDepth, p, i); } } }
public void LockTakenRecursively() { Padlock p1 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1); RecursiveFunction(5, 0, p1, i); using (p1.Lock()) { Assert.AreEqual(i.Value, 5); } }
public void TwoLocksSecondNotTaken() { Padlock p1 = new Padlock(); Padlock p2 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1, p2); //Access value outside of both locks. using (p1.Lock()) { i.Value++; } }
public void TwoLocksBothTaken() { Padlock p1 = new Padlock(); Padlock p2 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1, p2); using (p1.Lock()) { using (p2.Lock()) { i.Value++; Assert.AreEqual(i.Value, 1); } } }
public void OneLockTaken() { Padlock p1 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1); using (p1.Lock()) { i.Value++; Assert.AreEqual(i.Value, 1); } }
/// <summary> /// Initialize the random number generator /// </summary> static StaticRandom() { _padlock = new Padlock(); _random = new ThreadShared<Random>(new Random(), _padlock); }
public void Constructor_ConstructWithNoName() { Padlock p1 = new Padlock(); Assert.IsTrue(p1.Name.StartsWith("Padlock-")); }
public void OnePadlockToMultipleResources() { Padlock p1 = new Padlock(); ThreadShared<int> i1 = new ThreadShared<int>(0, p1); ThreadShared<int> i2 = new ThreadShared<int>(0, p1); //Can access both ThreadShared in same block... using (p1.Lock()) { i1.Value++; i2.Value++; } //... or individually using (p1.Lock()) { i1.Value++; } using (p1.Lock()) { i2.Value++; } using(p1.Lock()) { Assert.AreEqual(i1.Value, 2); Assert.AreEqual(i2.Value, 2); Assert.AreEqual(i1.Value, i2.Value); } }
public void Constructor_ConstructWithName() { Padlock p1 = new Padlock("PadlockX"); Assert.IsTrue(p1.Name.Equals("PadlockX")); }
public void ExceptionThrownWhileLockHeld() { Padlock p1 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1); try { using (p1.Lock()) { i.Value++; throw new InvalidOperationException(); } } catch (InvalidOperationException) { } //Locks should have been released. Create a new thread //to obtain the lock to ensure no deadlocks ensue. Thread secondThread = new Thread(delegate() { using (p1.Lock()) { i.Value++; } }); secondThread.Start(); secondThread.Join(); using (p1.Lock()) { Assert.AreEqual(i.Value, 2); } }
public void Constructor_AllPadlocksValid() { Padlock p1 = new Padlock(); Padlock p2 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1, p2); }
public void OneLockNotTaken() { Padlock p1 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1); //Access value outside of lock. i.Value++; }
/// <summary> /// Creates a new LockToken and associates it with the supplied parent /// </summary> internal LockToken(Padlock parent) { Insist.IsNotNull(parent, "parent"); _parent = parent; }
public void ValueGettersAreEqual() { Padlock p1 = new Padlock(); ThreadShared<int> i = new ThreadShared<int>(0, p1); using (p1.Lock()) { Assert.AreEqual(i.Value, i._); i.Value++; Assert.AreEqual(i.Value, i._); Assert.AreEqual(i.Value, 1); Assert.AreEqual(i._, 1); i._++; Assert.AreEqual(i.Value, i._); Assert.AreEqual(i.Value, 2); Assert.AreEqual(i._, 2); } }