[cominterop] Add coop handle enter/return on native CCW methods (#21365)
commit1734a7d60bd156cf78a0d9745557ed73c4f95055
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Mon, 13 Dec 2021 19:40:03 +0000 (13 14:40 -0500)
committerGitHub <noreply@github.com>
Mon, 13 Dec 2021 19:40:03 +0000 (13 14:40 -0500)
tree1ec5114165c4418685ee23f853c353c1b9e6eebd
parent640225161b07d0053c8d973d90a638b2aae620f6
[cominterop] Add coop handle enter/return on native CCW methods  (#21365)

* [tests] Add CCW GetIUnknownForObject leak test

* [cominterop] Add coop handle enter/return on native CCW methods

The CCW methods for IUnknown (and in principle IDispatch - except they all have
trivial bodies) are native C code in the runtime that may allocate coop
handles.  Add a coop handle frame around the entire call in order to make sure
they're cleaned up and don't retain a reference.

This helps fix managed object leaks with code like:

```
   var o  = new SomeClass();
   var pUnk = Marshal.GetIUnknownForObject(o);
   int c = Marshal.Release(pUnk);
   o = null;
```

Which retains a reference to the `SomeClass` instance that won't be collected
until the thread dies, despite cleaning up the IUnknown refcount. The underling
ccw addref/release methods leak coop handles on the thread.

This is not an issue when the CCW calls some managed method because there are
no coop handles there until some icall (at which point it will set up the
coop handle stack properly).
mono/metadata/cominterop.c
mono/tests/cominterop.cs