2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Threading;
5 using System.Runtime.InteropServices;
6 using System.Runtime.CompilerServices;
7 using MonoTests.Helpers;
9 public class Toggleref {
12 public List<object> link = new List<object> ();
13 public const int DROP = 0;
14 public const int STRONG = 1;
15 public const int WEAK = 2;
22 [StructLayout (LayoutKind.Explicit)]
23 public struct Helper {
28 public static IntPtr ObjToPtr (object obj)
30 Helper h = default (Helper);
37 static WeakReference<Toggleref> root, child;
39 [DllImport ("__Internal", EntryPoint="mono_gc_toggleref_add")]
40 static extern int mono_gc_toggleref_add (IntPtr ptr, bool strong_ref);
42 static void Register (object obj)
44 mono_gc_toggleref_add (Helper.ObjToPtr (obj), true);
47 static Toggleref a, b;
49 static void SetupLinks () {
50 var r = new Toggleref () { id = "root" };
51 var c = new Toggleref () { id = "child" };
53 r.__test = Toggleref.STRONG;
54 c.__test = Toggleref.WEAK;
57 root = new WeakReference<Toggleref> (r, false);
58 child = new WeakReference<Toggleref> (c, false);
61 static int test_0_root_keeps_child ()
63 Console.WriteLine ("test_0_root_keeps_child");
64 FinalizerHelpers.PerformNoPinAction (SetupLinks);
67 GC.WaitForPendingFinalizers ();
69 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
70 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
71 Console.WriteLine ("a is null {0}", a == null);
72 Console.WriteLine ("b is null {0}", b == null);
73 if (a == null || b == null)
75 Console.WriteLine ("a test {0}", a.__test);
76 Console.WriteLine ("b test {0}", b.__test);
78 //now we break the link and switch b to strong
80 b.__test = Toggleref.STRONG;
84 GC.WaitForPendingFinalizers ();
86 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
87 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
88 Console.WriteLine ("a is null {0}", a == null);
89 Console.WriteLine ("b is null {0}", b == null);
90 if (a == null || b == null)
92 Console.WriteLine ("a test {0}", a.__test);
93 Console.WriteLine ("b test {0}", b.__test);
99 static void SetupLinks2 () {
100 var r = new Toggleref () { id = "root" };
101 var c = new Toggleref () { id = "child" };
103 r.__test = Toggleref.STRONG;
104 c.__test = Toggleref.WEAK;
107 root = new WeakReference<Toggleref> (r, false);
108 child = new WeakReference<Toggleref> (c, false);
111 static int test_0_child_goes_away ()
113 Console.WriteLine ("test_0_child_goes_away");
115 FinalizerHelpers.PerformNoPinAction (SetupLinks2);
118 GC.WaitForPendingFinalizers ();
120 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
121 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
122 Console.WriteLine ("a is null {0}", a == null);
123 Console.WriteLine ("b is null {0}", b == null);
124 if (a == null || b != null)
126 Console.WriteLine ("a test {0}", a.__test);
131 static ConditionalWeakTable<Toggleref, object> cwt = new ConditionalWeakTable<Toggleref, object> ();
132 static WeakReference<object> root_value, child_value;
133 static object a_val, b_val;
136 static void SetupLinks3 () {
137 var r = new Toggleref () { id = "root" };
138 var c = new Toggleref () { id = "child" };
140 r.__test = Toggleref.STRONG;
141 c.__test = Toggleref.WEAK;
144 root = new WeakReference<Toggleref> (r, false);
145 child = new WeakReference<Toggleref> (c, false);
147 var root_val = new object ();
148 var child_val = new object ();
150 cwt.Add (r, root_val);
151 cwt.Add (c, child_val);
153 root_value = new WeakReference<object> (root_val, false);
154 child_value = new WeakReference<object> (child_val, false);
157 static int test_0_CWT_keep_child_alive ()
159 Console.WriteLine ("test_0_CWT_keep_child_alive");
161 FinalizerHelpers.PerformNoPinAction (SetupLinks3);
164 GC.WaitForPendingFinalizers ();
166 Console.WriteLine ("try get A {0}", root.TryGetTarget (out a));
167 Console.WriteLine ("try get B {0}", child.TryGetTarget (out b));
168 Console.WriteLine ("a is null {0}", a == null);
169 Console.WriteLine ("b is null {0}", b == null);
170 if (a == null || b != null)
172 Console.WriteLine ("a test {0}", a.__test);
174 Console.WriteLine ("try get a_val {0}", root_value.TryGetTarget (out a_val));
175 Console.WriteLine ("try get v_val {0}", child_value.TryGetTarget (out b_val));
177 //the strong toggleref must keep the CWT value to remains alive
181 //the weak toggleref should allow the CWT value to go away
185 object res_value = null;
186 bool res = cwt.TryGetValue (a, out res_value);
187 Console.WriteLine ("CWT result {0} -> {1}", res, res_value == a_val);
189 //the strong val is not on the CWT
193 //for some reason the value is not the right one
194 if (res_value != a_val)
200 static int Main (string[] args)
202 return TestDriver.RunTests (typeof (Driver), args);