2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Threading;
5 using System.Runtime.InteropServices;
6 using System.Runtime.CompilerServices;
8 public class Toggleref {
11 public List<object> link = new List<object> ();
12 public const int DROP = 0;
13 public const int STRONG = 1;
14 public const int WEAK = 2;
21 [StructLayout (LayoutKind.Explicit)]
22 public struct Helper {
27 public static IntPtr ObjToPtr (object obj)
29 Helper h = default (Helper);
36 static WeakReference<Toggleref> root, child;
38 [DllImport ("__Internal", EntryPoint="mono_gc_toggleref_add")]
39 static extern int mono_gc_toggleref_add (IntPtr ptr, bool strong_ref);
41 static void Register (object obj)
43 mono_gc_toggleref_add (Helper.ObjToPtr (obj), true);
46 static Toggleref a, b;
48 static void SetupLinks () {
49 var r = new Toggleref () { id = "root" };
50 var c = new Toggleref () { id = "child" };
52 r.__test = Toggleref.STRONG;
53 c.__test = Toggleref.WEAK;
56 root = new WeakReference<Toggleref> (r, false);
57 child = new WeakReference<Toggleref> (c, false);
60 static int test_0_root_keeps_child ()
62 Console.WriteLine ("test_0_root_keeps_child");
63 var t = new Thread (SetupLinks);
68 GC.WaitForPendingFinalizers ();
70 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
71 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
72 Console.WriteLine ("a is null {0}", a == null);
73 Console.WriteLine ("b is null {0}", b == null);
74 if (a == null || b == null)
76 Console.WriteLine ("a test {0}", a.__test);
77 Console.WriteLine ("b test {0}", b.__test);
79 //now we break the link and switch b to strong
81 b.__test = Toggleref.STRONG;
85 GC.WaitForPendingFinalizers ();
87 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
88 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
89 Console.WriteLine ("a is null {0}", a == null);
90 Console.WriteLine ("b is null {0}", b == null);
91 if (a == null || b == null)
93 Console.WriteLine ("a test {0}", a.__test);
94 Console.WriteLine ("b test {0}", b.__test);
100 static void SetupLinks2 () {
101 var r = new Toggleref () { id = "root" };
102 var c = new Toggleref () { id = "child" };
104 r.__test = Toggleref.STRONG;
105 c.__test = Toggleref.WEAK;
108 root = new WeakReference<Toggleref> (r, false);
109 child = new WeakReference<Toggleref> (c, false);
112 static int test_0_child_goes_away ()
114 Console.WriteLine ("test_0_child_goes_away");
116 var t = new Thread (SetupLinks2);
121 GC.WaitForPendingFinalizers ();
123 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
124 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
125 Console.WriteLine ("a is null {0}", a == null);
126 Console.WriteLine ("b is null {0}", b == null);
127 if (a == null || b != null)
129 Console.WriteLine ("a test {0}", a.__test);
134 static ConditionalWeakTable<Toggleref, object> cwt = new ConditionalWeakTable<Toggleref, object> ();
135 static WeakReference<object> root_value, child_value;
136 static object a_val, b_val;
139 static void SetupLinks3 () {
140 var r = new Toggleref () { id = "root" };
141 var c = new Toggleref () { id = "child" };
143 r.__test = Toggleref.STRONG;
144 c.__test = Toggleref.WEAK;
147 root = new WeakReference<Toggleref> (r, false);
148 child = new WeakReference<Toggleref> (c, false);
150 var root_val = new object ();
151 var child_val = new object ();
153 cwt.Add (r, root_val);
154 cwt.Add (c, child_val);
156 root_value = new WeakReference<object> (root_val, false);
157 child_value = new WeakReference<object> (child_val, false);
160 static int test_0_CWT_keep_child_alive ()
162 Console.WriteLine ("test_0_CWT_keep_child_alive");
164 var t = new Thread (SetupLinks3);
169 GC.WaitForPendingFinalizers ();
171 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
172 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
173 Console.WriteLine ("a is null {0}", a == null);
174 Console.WriteLine ("b is null {0}", b == null);
175 if (a == null || b != null)
177 Console.WriteLine ("a test {0}", a.__test);
179 Console.WriteLine ("try get a_val {0}", root_value.TryGetTarget (out a_val));
180 Console.WriteLine ("try get v_val {0}", child_value.TryGetTarget (out b_val));
182 //the strong toggleref must keep the CWT value to remains alive
186 //the weak toggleref should allow the CWT value to go away
190 object res_value = null;
191 bool res = cwt.TryGetValue (a, out res_value);
192 Console.WriteLine ("CWT result {0} -> {1}", res, res_value == a_val);
194 //the strong val is not on the CWT
198 //for some reason the value is not the right one
199 if (res_value != a_val)
205 static int Main (string[] args)
207 return TestDriver.RunTests (typeof (Driver), args);