diff --git a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs index 1e8d4dbae..95b907ea4 100644 --- a/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs +++ b/src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs @@ -146,9 +146,8 @@ public virtual void DisposePeer (IJavaPeerable value) if (!value.PeerReference.IsValid) return; - RemovePeer (value); - value.Disposed (); + RemovePeer (value); var h = value.PeerReference; if (!h.IsValid) diff --git a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj index 24fb0a335..2537a2f4a 100644 --- a/tests/Java.Interop-Tests/Java.Interop-Tests.csproj +++ b/tests/Java.Interop-Tests/Java.Interop-Tests.csproj @@ -40,6 +40,7 @@ + diff --git a/tests/Java.Interop-Tests/Java.Interop/GetThis.cs b/tests/Java.Interop-Tests/Java.Interop/GetThis.cs new file mode 100644 index 000000000..227d2b50e --- /dev/null +++ b/tests/Java.Interop-Tests/Java.Interop/GetThis.cs @@ -0,0 +1,47 @@ +using System; + +using Java.Interop; + +namespace Java.InteropTests +{ + [JniTypeSignature (GetThis.JniTypeName)] + public class GetThis : JavaObject + { + internal const string JniTypeName = "com/xamarin/interop/GetThis"; + + bool _isDisposed; + + readonly static JniPeerMembers _members = new JniPeerMembers (JniTypeName, typeof (GetThis)); + + public override JniPeerMembers JniPeerMembers { + get {return _members;} + } + + public GetThis () + { + } + + public unsafe GetThis This { + get { + var o = _members.InstanceMethods.InvokeNonvirtualObjectMethod ("getThis.()Lcom/xamarin/interop/GetThis;", this, null); + return JniEnvironment.Runtime.ValueManager.GetValue (ref o, JniObjectReferenceOptions.CopyAndDispose); + } + } + + protected override void Dispose (bool disposing) + { + if (_isDisposed) { + return; + } + _isDisposed = true; + if (disposing) { + var t = This; + if (t != this) { + throw new InvalidOperationException ("SHOULD NOT BE REACHED"); + } + } + base.Dispose (disposing); + } + } +} + diff --git a/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs b/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs index bf65b4b84..6ce8935f0 100644 --- a/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs +++ b/tests/Java.Interop-Tests/Java.Interop/JavaObjectTest.cs @@ -193,6 +193,14 @@ public void NestedDisposeInvocations () value.Dispose (); value.Dispose (); } + + [Test] + public void DisposeAccessesThis () + { + var value = new GetThis (); + value.Dispose (); + value.Dispose (); + } } class JavaObjectWithNoJavaPeer : JavaObject { diff --git a/tests/Java.Interop-Tests/java/com/xamarin/interop/GetThis.java b/tests/Java.Interop-Tests/java/com/xamarin/interop/GetThis.java new file mode 100644 index 000000000..89cdc53f9 --- /dev/null +++ b/tests/Java.Interop-Tests/java/com/xamarin/interop/GetThis.java @@ -0,0 +1,42 @@ +package com.xamarin.interop; + +import java.util.ArrayList; + +import com.xamarin.java_interop.GCUserPeerable; + +public class GetThis implements GCUserPeerable { + + static final String assemblyQualifiedName = "Java.InteropTests.GetThis, Java.Interop-Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; + static { + com.xamarin.java_interop.ManagedPeer.registerNativeMembers ( + GetThis.class, + assemblyQualifiedName, + ""); + } + + ArrayList managedReferences = new ArrayList(); + + public GetThis () { + if (GetThis.class == getClass ()) { + com.xamarin.java_interop.ManagedPeer.construct ( + this, + "Java.InteropTests.GetThis, Java.Interop-Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", + "" + ); + } + } + + public final GetThis getThis() { + return this; + } + + public void jiAddManagedReference (java.lang.Object obj) + { + managedReferences.add (obj); + } + + public void jiClearManagedReferences () + { + managedReferences.clear (); + } +}