2 using System
.Threading
;
3 using System
.Runtime
.InteropServices
;
5 [StructLayout(LayoutKind
.Explicit
)]
6 internal struct ObjectWrapper
{
7 [FieldOffset(0)] object obj
;
8 [FieldOffset(0)] IntPtr handle
;
10 internal static IntPtr
Convert (object obj
) {
11 ObjectWrapper wrapper
= new ObjectWrapper ();
15 return wrapper
.handle
;
18 internal static object Convert (IntPtr ptr
)
20 ObjectWrapper wrapper
= new ObjectWrapper ();
31 public static bool fail
;
32 public static Test1 instance
;
35 if (self
.Target
== null)
43 public static bool fail
;
44 public static Test2 instance
;
47 if (self
.Target
== null)
54 public static int Main (String
[] args
) {
55 return TestDriver
.RunTests (typeof (Tests
), args
);
58 static void create1 () {
59 Test1
.instance
= new Test1 ();
60 Test1
.instance
.self
= GCHandle
.Alloc (Test1
.instance
, GCHandleType
.WeakTrackResurrection
);
61 Test1
.instance
= null;
64 public static unsafe int test_0_track_resurrection () {
65 /* The GCHandle should not be cleared before calling the finalizers */
68 GC
.WaitForPendingFinalizers ();
70 // WaitForPendingFinalizers doesn't seem to work ?
71 System
.Threading
.Thread
.Sleep (100);
72 /* If the finalizers do not get ran by this time, the test will still succeed */
73 return Test1
.fail
? 1 : 0;
76 static void create2 () {
77 Test2
.instance
= new Test2 ();
78 object o
= new object ();
79 Test2
.instance
.self
= GCHandle
.Alloc (o
, GCHandleType
.WeakTrackResurrection
);
80 Test2
.instance
.self
.Target
= Test2
.instance
;
81 Test2
.instance
= null;
84 public static int test_0_track_resurrection_set_target () {
85 /* Same test but the handle target is set dynamically after it is created */
88 GC
.WaitForPendingFinalizers ();
90 System
.Threading
.Thread
.Sleep (100);
91 return Test2
.fail
? 1 : 0;
94 static GCHandle handle
;
95 static IntPtr original_addr
;
97 static void alloc_handle () {
98 var obj
= new object ();
99 handle
= GCHandle
.Alloc (obj
, GCHandleType
.Pinned
);
100 original_addr
= ObjectWrapper
.Convert (obj
);
103 public static int test_0_pinned_handle_pins_target () {
104 var t
= new Thread (alloc_handle
);
109 var newAddr
= ObjectWrapper
.Convert (handle
.Target
);
111 return original_addr
== newAddr
? 0 : 1;