[DllImport ("libtest", EntryPoint="mono_test_marshal_return_delegate_delegate")]
public static extern int mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d);
+ [DllImport ("libtest", EntryPoint="mono_test_marshal_delegate_ref_delegate")]
+ public static extern int mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del);
+
+ [DllImport ("libtest", EntryPoint="mono_test_marshal_virtual_delegate")]
+ public static extern int mono_test_marshal_virtual_delegate (VirtualDelegate del);
+
+ [DllImport ("libtest", EntryPoint="mono_test_marshal_icall_delegate")]
+ public static extern int mono_test_marshal_icall_delegate (IcallDelegate del);
+
+ public delegate string IcallDelegate (IntPtr p);
+
public delegate int TestDelegate (int a, ref SimpleStruct ss, int b);
public delegate SimpleStruct SimpleDelegate2 (SimpleStruct ss);
public delegate return_int_delegate ReturnDelegateDelegate ();
+ public delegate int DelegateByrefDelegate (ref return_int_delegate del);
+
+ public delegate int VirtualDelegate (int i);
+
public static int Main () {
return TestDriver.RunTests (typeof (Tests));
}
return mono_test_marshal_return_delegate_delegate (new ReturnDelegateDelegate (return_delegate));
}
+ public static int return_plus_1 (int i) {
+ return i + 1;
+ }
+
+ public static int ref_delegate_delegate (ref return_int_delegate del) {
+ del = return_plus_1;
+ return 0;
+ }
+
+ public static int test_55_marshal_delegate_ref_delegate () {
+ var del = new DelegateByrefDelegate (ref_delegate_delegate);
+ return mono_test_marshal_delegate_ref_delegate (del);
+ }
+
/* Passing and returning strings */
public delegate String ReturnStringDelegate (String s);
return mono_test_marshal_array_delegate1 (null, 0, new ArrayDelegate1 (array_delegate2));
}
+ public delegate int ArrayDelegateBlittable (int i, string j,
+ [In, MarshalAs(UnmanagedType.LPArray,
+ ArraySubType=UnmanagedType.LPStr, SizeParamIndex=0)] int[] arr);
+
+ [DllImport ("libtest", EntryPoint="mono_test_marshal_array_delegate")]
+ public static extern int mono_test_marshal_array_delegate1 (string[] arr, int len, ArrayDelegateBlittable d);
+
+ public static int array_delegate_null_blittable (int i, string j, int[] arr) {
+ return (arr == null) ? 0 : 1;
+ }
+
+ public static int test_0_marshal_array_delegate_null_blittable () {
+ return mono_test_marshal_array_delegate1 (null, 0, new ArrayDelegateBlittable (array_delegate_null_blittable));
+ }
+
public delegate int ArrayDelegate3 (int i,
string j,
[In, MarshalAs(UnmanagedType.LPArray,
return res;
}
+ class Worker {
+ volatile bool stop = false;
+ public void Stop () {
+ stop = true;
+ }
+
+ public void Work () {
+ while (!stop) {
+ for (int i = 0; i < 100; i++) {
+ var a = new double[80000];
+ Thread.Sleep (0);
+ }
+ GC.Collect ();
+ }
+ }
+ }
+
+ public static int test_43_thread_attach_detach_contested () {
+ // Test plan: we want to create a race between the GC
+ // and native threads detaching. When a native thread
+ // calls a managed delegate, it's attached to the
+ // runtime by the wrapper. It is detached when the
+ // thread is destroyed and the TLS key destructor for
+ // MonoThreadInfo runs. That destructor wants to take
+ // the GC lock. So we create a lot of native threads
+ // while at the same time running a worker that
+ // allocates garbage and invokes the collector.
+ var w = new Worker ();
+ Thread t = new Thread(new ThreadStart (w.Work));
+ t.Start ();
+
+ for (int count = 0; count < 500; count++) {
+ int res = mono_test_marshal_thread_attach (delegate (int i) {
+ Thread.Sleep (0);
+ return i + 1;
+ });
+ }
+ Thread.Sleep (1000);
+ w.Stop ();
+ t.Join ();
+ return 43;
+
+ }
/*
* Appdomain save/restore
*/
return 0;
}
}
+
+ class Base {
+ public VirtualDelegate get_del () {
+ return delegate_test;
+ }
+
+ public virtual int delegate_test (int i) {
+ return i;
+ }
+ }
+
+ class Derived : Base {
+ public override int delegate_test (int i) {
+ return i + 1;
+ }
+ }
+
+ public static int test_43_virtual () {
+ Base b = new Derived ();
+
+ return mono_test_marshal_virtual_delegate (b.get_del ());
+ }
+
+ public static int test_0_icall_delegate () {
+ var m = typeof (Marshal).GetMethod ("PtrToStringAnsi", new Type[] { typeof (IntPtr) });
+
+ return mono_test_marshal_icall_delegate ((IcallDelegate)Delegate.CreateDelegate (typeof (IcallDelegate), m));
+ }
}