online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
using System; using System.Threading; public sealed class MutexLock<T> { internal readonly object _lock = new object(); internal T _guardedValue; public MutexLock() { } public MutexLock(T value) { _guardedValue = value; } public AcquiredMutex<T> Acquire() { Monitor.Enter(_lock); return new AcquiredMutex<T>(this); } } public struct AcquiredMutex<T>: IDisposable { private MutexLock<T> _owner; internal AcquiredMutex(MutexLock<T> owner) { _owner = owner; } public void Dispose() { var owner = _owner; if (owner == null) return; _owner = null; Monitor.Exit(owner._lock); } public ref T Value => ref _owner._guardedValue; // Because this struct is going to be used with the "using" clause, the // property Value is assumed as readonly by the compiler, while the return // of a method that does exactly the same is not. // Yet, members of Value (if it has mutable fields or properties) don't suffer // such a readonly enforcement from the compiler. public ref T MutableValue() => ref _owner._guardedValue; } class Program { static void Main() { var mutex = new MutexLock<(int id, string name)>((12, "This is a string")); // The following would cause a compile-time error. //Console.WriteLine(mutex.Value); using (var locked = mutex.Acquire()) { Console.WriteLine(locked.Value); // Because of an annoying trait of using(), the compiler assumes we // cannot modify any field or property of "locked". Yet, a ref result from // a method, not a property, is OK... that's why I added that // MutableValue method. locked.MutableValue() = (15, "Test"); // Just showing that the value was updated. Console.WriteLine(locked.Value); // Just to show that the locks work, we are scheduling an item to Run // that will also use the MutexLock... but then we will wait for 3 seconds // before releasing the lock. For this sample, it should force the // secondary thread to wait and prove that the locks are working. ThreadPool.QueueUserWorkItem ( (_) => { using (var newLocked = mutex.Acquire()) Console.WriteLine("Secondary thread acquired the lock. Values are: " + newLocked.Value); } ); Thread.Sleep(3000); // Notice that we only change things at the end of the scope. So, the // secondary thread should read the new name. Also notice that Updating // a field of Value (instead of trying to replace Value) is allowed. locked.Value.id = 16; locked.Value.name = "Updating a field of Value."; } Thread.Sleep(1000); } }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue