You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[tests] rework JavaObjectTest, use FinalizerHelper from mono/mono (#899)
Context: dotnet/android#6363
Context: dotnet/runtime#60638 (comment)
Context: d1d64c1
Context: dotnet/android@c2c9ed4
We were seeing `JavaObjectTest.Dispose_Finalized()` fail in a .NET 6
bump in xamarin-android with `$(UseInterpreter)` set to `true`:
Expected: True
But was: False
at Java.InteropTests.JavaObjectTest.Dispose_Finalized()
at System.Reflection.RuntimeMethodInfo.Invoke(Object , BindingFlags , Binder , Object[] , CultureInfo )
The first recommendation was to use a helper method from mono/mono's
unit tests:
* https://github.com/mono/mono/blob/8266c5604b8c03882f2b06af27fdea46b142d6b9/mono/mini/TestHelpers.cs#L12
I removed usage of all `System.Threading` in `JavaObjectTest` in
favor of this helper method, which internally uses a `Thread`.
This did not solve this issue; we need to fix up the test to wait for
two GCs to complete, on two separate threads:
FinalizerHelpers.PerformNoPinAction (() => {
FinalizerHelpers.PerformNoPinAction (() => {
var v = new JavaDisposedObject (() => d = true, () => f = true);
GC.KeepAlive (v);
});
// Thread 2
JniEnvironment.Runtime.ValueManager.CollectPeers ();
});
// Thread 1
JniEnvironment.Runtime.ValueManager.CollectPeers ();
`ValueManager.CollectPeers()` uses `GC.Collect()`, and `GC.Collect()`
needs to be called from two separate threads because, as per @BrzVlad:
> if an object is alive then the GC will scan it and, by doing so, it
> will probably store it in the stack somewhere. In very unfortunate
> scenarios, at the second collection, the pinning step will find this
> reference existing on the stack and will pin the object (that might
> have now been dead otherwise). Because the `JavaDisposedObject` is
> alive during the first collection, we do this collection on a
> separate thread, so the second GC doesn't get to find this left over
> references on the stack.
With this change in place, the test now passes.
We can also remove the category added in d1d64c1.
0 commit comments