1 //
2 // Copyright (c) 2010-2025 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 
8 using Antmicro.Renode.Debugging;
9 
10 namespace Antmicro.Renode.Utilities
11 {
12     public class SealableValue<T> where T: struct
13     {
Seal()14         public DisposableWrapper Seal()
15         {
16             lock(locker)
17             {
18                 lockCounter++;
19                 return DisposableWrapper.New(Unseal);
20             }
21         }
22 
23         public T Value
24         {
25             get => innerValue;
26             set
27             {
28                 lock(locker)
29                 {
30                     deferredValue = value;
31                     if(IsLocked)
32                     {
33                         return;
34                     }
35                     innerValue = value;
36                 }
37             }
38         }
39 
Unseal()40         private void Unseal()
41         {
42             // This function should be only used by DisposableWrapper.Dispose()
43             lock(locker)
44             {
45                 DebugHelper.Assert(IsLocked);
46                 lockCounter--;
47 
48                 if(!IsLocked)
49                 {
50                     innerValue = deferredValue;
51                 }
52             }
53         }
54 
55         private bool IsLocked => lockCounter > 0;
56 
57         private T innerValue;
58         private T deferredValue;
59 
60         private uint lockCounter;
61         private readonly object locker = new object();
62     }
63 }
64