1 #region Copyright notice and license 2 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.Threading; 21 22 namespace Grpc.Core.Internal 23 { 24 internal class AtomicCounter 25 { 26 long counter = 0; 27 AtomicCounter(long initialCount = 0)28 public AtomicCounter(long initialCount = 0) 29 { 30 this.counter = initialCount; 31 } 32 Increment()33 public long Increment() 34 { 35 return Interlocked.Increment(ref counter); 36 } 37 IncrementIfNonzero(ref bool success)38 public void IncrementIfNonzero(ref bool success) 39 { 40 long origValue = counter; 41 while (true) 42 { 43 if (origValue == 0) 44 { 45 success = false; 46 return; 47 } 48 long result = Interlocked.CompareExchange(ref counter, origValue + 1, origValue); 49 if (result == origValue) 50 { 51 success = true; 52 return; 53 }; 54 origValue = result; 55 } 56 } 57 Decrement()58 public long Decrement() 59 { 60 return Interlocked.Decrement(ref counter); 61 } 62 63 public long Count 64 { 65 get 66 { 67 return Interlocked.Read(ref counter); 68 } 69 } 70 } 71 } 72