예제 #1
0
            private T RetrieveClone(Transact transaction)
            {
                if (ReferenceEquals(transaction, null))
                {
                    return(base.Value);
                }
                object value;

                Volatile.Write(ref _inUse, 1);
                if (transaction._writeLog.TryGetValue(this, out value))
                {
                    return((T)value);
                }
                if (transaction._readLog.TryGetValue(this, out value))
                {
                    return((T)value);
                }
                var original = RetrieveValue(transaction._parentTransaction);
                var clone    = _cloner.Clone(original);

                if (!_comparer.Equals(clone, original))
                {
                    transaction._writeLog.Set(this, clone);
                }

                transaction._readLog.TryAdd(this, original);

                return(clone);
            }
예제 #2
0
            private T RetrieveValue(Transact transaction)
            {
                if (ReferenceEquals(transaction, null))
                {
                    return(base.Value);
                }
                else
                {
                    object value;
                    Volatile.Write(ref _inUse, 1);
                    if (transaction._writeLog.TryGetValue(this, out value))
                    {
                        return((T)value);
                    }
                    if (transaction._readLog.TryGetValue(this, out value))
                    {
                        return((T)value);
                    }
                    var original = RetrieveValue(transaction._parentTransaction);

                    transaction._readLog.TryAdd(this, original);

                    return(original);
                }
            }
예제 #3
0
파일: Transact.cs 프로젝트: qwertie/Theraot
 public Transact()
 {
     _writeLog = new WeakHashBucket<IResource, object, WeakNeedle<IResource>>();
     _readLog = new WeakHashBucket<IResource, object, WeakNeedle<IResource>>();
     _parentTransaction = _currentTransaction;
     _currentTransaction = this;
 }
예제 #4
0
 public Transact()
 {
     WriteLog            = new ThreadSafeDictionary <IResource, object>();
     ReadLog             = new ThreadSafeDictionary <IResource, object>();
     ParentTransaction   = _currentTransaction;
     _currentTransaction = this;
     _thread             = Thread.CurrentThread;
 }
예제 #5
0
 public Transact()
 {
     _writeLog           = new SafeDictionary <IResource, object>();
     _readLog            = new SafeDictionary <IResource, object>();
     _parentTransaction  = _currentTransaction;
     _currentTransaction = this;
     _thread             = Thread.CurrentThread;
 }
예제 #6
0
 private void StoreValue(Transact transaction, T value)
 {
     if (!IsAlive || ReferenceEquals(transaction, null))
     {
         base.Value = value;
     }
     else
     {
         transaction._writeLog.Set(this, value);
     }
 }
예제 #7
0
 private void StoreValue(Transact transaction, T value)
 {
     if (!IsAlive || transaction == null)
     {
         base.Value = value;
     }
     else
     {
         Volatile.Write(ref _inUse, 1);
         transaction.WriteLog.Set(this, value);
     }
 }
예제 #8
0
 private void Release(bool dispose)
 {
     for (var currentTransaction = _currentTransaction; currentTransaction != null && currentTransaction != this; currentTransaction = currentTransaction.ParentTransaction)
     {
         if (dispose)
         {
             currentTransaction.Dispose();
         }
         else
         {
             currentTransaction.Release();
         }
     }
     Release();
     if (dispose)
     {
         _currentTransaction = ParentTransaction;
     }
 }
예제 #9
0
        private T RetrieveValue(Transact transaction)
        {
            if (transaction == null)
            {
                return(base.Value);
            }
            Volatile.Write(ref _inUse, 1);
            if (transaction.WriteLog.TryGetValue(this, out var value))
            {
                return((T)value);
            }
            if (transaction.ReadLog.TryGetValue(this, out value))
            {
                return((T)value);
            }
            var original = RetrieveValue(transaction.ParentTransaction);

            transaction.ReadLog.TryAdd(this, original);

            return(original);
        }
예제 #10
0
파일: Transact.cs 프로젝트: qwertie/Theraot
 private void Rollback(bool disposing)
 {
     Transact currentTransaction;
     do
     {
         currentTransaction = _currentTransaction;
         if (ReferenceEquals(currentTransaction, this))
         {
             break;
         }
         else
         {
             if (disposing)
             {
                 currentTransaction.Dispose();
             }
             else
             {
                 currentTransaction.Rollback(false);
             }
         }
     }
     while (true);
     Uncapture();
     if (disposing)
     {
         _readLog.AutoRemoveDeadItems = false;
         _writeLog.AutoRemoveDeadItems = false;
         _currentTransaction = _currentTransaction._parentTransaction;
     }
 }
예제 #11
0
 public void Transact_RaceCondition()
 {
     var handle = new ManualResetEvent(false);
     int[] count = { 0, 0 };
     var needle = Transact.CreateNeedle(5);
     var winner = 0;
     Assert.AreEqual(needle.Value, 5);
     Task.Factory.StartNew
     (
         () =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 needle.Value += 2;
                 if (transact.Commit())
                 {
                     winner = 1;
                 }
                 Interlocked.Increment(ref count[1]);
             }
         }
     );
     Task.Factory.StartNew
     (
         () =>
         {
             using (var transact = new Transact())
             {
                 Interlocked.Increment(ref count[0]);
                 handle.WaitOne();
                 needle.Value += 5;
                 if (transact.Commit())
                 {
                     winner = 2;
                 }
                 Interlocked.Increment(ref count[1]);
             }
         }
     );
     while (Thread.VolatileRead(ref count[0]) != 2)
     {
         Thread.Sleep(0);
     }
     handle.Set();
     while (Thread.VolatileRead(ref count[1]) != 2)
     {
         Thread.Sleep(0);
     }
     // One, the other, or both
     Trace.WriteLine("Winner: " + winner);
     Trace.WriteLine("Value: " + needle.Value);
     Assert.IsTrue((winner == 1 && needle.Value == 7) || (winner == 2 && needle.Value == 10) || (needle.Value == 12));
     handle.Close();
 }