Merge pull request #2545 from ermshiperete/Xamarin-24974
authormonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 4 Apr 2016 20:11:31 +0000 (21:11 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 4 Apr 2016 20:11:31 +0000 (21:11 +0100)
[corlib] Fix exception in __ComObject finalizer during shutdown

* keep a reference to a __ComObject's proxy so it doesn't get garbage
  collected
* don't create __ComObjects unnecessarily
* Fix for bug [24974](https://bugzilla.xamarin.com/show_bug.cgi?id=24974)

1  2 
mcs/class/corlib/System/__ComObject.cs

index a772d0fef9791888bd00475df9459c80dc2cc4d6,ac50ebfaea236153d53a873183519beb741e7e10..2e7e6066af533f349baeb1462d36c468c53ac937
@@@ -63,6 -63,9 +63,9 @@@ namespace Syste
                #endregion
  #pragma warning restore 169
  
+               // keep a reference to the proxy so it doesn't get garbage collected before the RCW
+               ComInteropProxy proxy;
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal static extern __ComObject CreateRCW (Type t);
  
  
                ~__ComObject ()
                {       
-                       if (synchronization_context != null)
-                               synchronization_context.Post ((state) => ReleaseInterfaces (), this);
-                       else
-                               ReleaseInterfaces ();                           
+                       if (hash_table != IntPtr.Zero) {
+                               if (synchronization_context != null)
+                                       synchronization_context.Post ((state) => ReleaseInterfaces (), this);
+                               else
+                                       ReleaseInterfaces ();
+                       }
+                       proxy = null;
                }
  
                public __ComObject ()
                        Initialize (t);
                }
  
-               internal __ComObject (IntPtr pItf)
+               internal __ComObject (IntPtr pItf, ComInteropProxy p)
                {
+                       proxy = p;
                        InitializeApartmentDetails ();
                        Guid iid = IID_IUnknown;
                        int hr = Marshal.QueryInterface (pItf, ref iid, out iunknown);
                        Marshal.ThrowExceptionForHR (hr);
                }
  
+               internal void Initialize (IntPtr pUnk, ComInteropProxy p)
+               {
+                       proxy = p;
+                       InitializeApartmentDetails ();
+                       iunknown = pUnk;
+               }
                internal void Initialize (Type t)
                {
                        InitializeApartmentDetails ();
                        if (iunknown != IntPtr.Zero)
                                return;
  
+                       iunknown = CreateIUnknown (t);
+               }
+               internal static IntPtr CreateIUnknown(Type t)
+               {
                        System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (t.TypeHandle);
-                       
+                       IntPtr iunknown;
                        ObjectCreationDelegate ocd = ExtensibleClassFactory.GetObjectCreationCallback (t);
                        if (ocd != null) {
                                iunknown = ocd (IntPtr.Zero);
                                int hr = CoCreateInstance (GetCLSID (t), IntPtr.Zero, 0x1 | 0x4 | 0x10, IID_IUnknown, out iunknown);
                                Marshal.ThrowExceptionForHR (hr);
                        }
+                       return iunknown;
                }
  
                private void InitializeApartmentDetails ()
                        out IntPtr pUnk);
        }
  }
 +#else
 +namespace System
 +{
 +      // this is a shim class so we can AOT during mobile_static build without --enable-minimal=com
 +      internal class __ComObject
 +      {
 +              __ComObject ()
 +              {
 +                      throw new NotSupportedException ();
 +              }
 +      }
 +}
  #endif