How to leverage DCOM garbage collector with custom marshaling? (IMarshal) - com

I'm working on a multi-tenant COM server that exposes classes with different interfaces in a hierarchy. Some of the classes implement IMarshal for more efficient custom marshaling using shared-memory for zero-copy exchange of immutable data buffers (based on "Inside COM+: Base Services" book). This works nicely but comes at the downside of losing automatic stub cleanup by the DCOM garbage collector if the client crashes or leaks handles. I've grown quite found of using COMGLB_FAST_RUNDOWN for fast stub cleanup after client crashes, and would very much like automatic cleanup also for IMarshal classes if possible.
I've already tried implementing IExternalConnection to intercept reference release events from the client-side proxy. However, this interface does not seem to be called for classes that also implement IMarshal. IFastRundown is similarly also not called for classes implementing IMarshal.
I'm reluctant to implementing my own watchdog to detect & handle client process crashes, since that would require manual bookkeeping of references held by each client for each object instance that implements IMarshal. This sounds like a lot of bookkeeping to me. Detecting the client process PID is furthermore inconvenient, especially if it needs to be done separately for each object reference due to the multi-tenant architecture. Leveraging the DCOM garbage collector would make everything much easier.
Any suggestions for how to enable the DCOM garbage collector also for classes implementing IMarshal?
I guess what I'm hoping for is some form of per-object event mechanism for being notified when client references are released that also sends an event if the client crashes.
Small reproducer project: https://github.com/forderud/SharedMemMarshal

Answering myself since I just found a solution to this problem.
It's possible to introduce an extra COM object for maintaining references from the client-side proxy back to the server.
The https://github.com/forderud/SharedMemMarshal project have been updated to do just this through a tiny RefOwner class that is marshalled using CoMarshalInterface/CoUnmarshalInterface from the server to the proxy. This both simplifies the impl. as well as hardening it to better cope with reference leaks and client process crashes.

Related

.NET Core DI Service Collection non modifiable service for integrity

I have been investing time into .NET core and the Dependency Injection model using the ServiceCollection object.
Is there any way to protect the integrity of the service implementations that have already been added to the collection?
I would like to know that the original implementation of a service I have added hasn't been modified or replaced at some point during runtime.
In the case of security, if I was an attacker who knew what I was doing and had a remote code execution vulnerability, I could replace a key service implementation and aim to hide with a form of persistence.
In the case of fool proofing, if I had a large project I would hate to have to go debugging why something went wrong to find out a developer replaces the implementation of a service that was in widespread use.
Any suggestions? Perhaps there is some protection that prevents this, or its just not a concern?
You could implement IServiceCollection manually, defining a class, with a List<ServiceDescriptor> to implement all methods declared in the interfaces.
Then, modify the methods that may change the values of the items which are registries, adding notifying operations to determine whether the values are changed.

Are there any alternative concepts for handling unmanaged resources in garbage collected languages?

Garbage collected object oriented programming languages reclaim unused memory automatically, but all other kinds of resources (i.e. files, sockets...) still require manual release since finalizers cannot be trusted to run in time (or at all).
Therefore such resource objects usually provide some kind of "close"- or "dispose"-method/pattern, which can be problematic for a number of reasons:
Dispose has to be called manually which may pose problems in cases when it is not clear when the resource has to be released (similar problem as with manual memory management)
The disposable-pattern is somewhat "viral", since each class containing a disposable resource must be made disposable as well in order to guarantee correct resource cleanup
An addition of a disposable member to a class, requiring the class to become disposable as well, changes the interface and the usage patterns of the class, thus breaking encapsulation
The disposable-pattern creates problems with inheritance, i.e. when a derived class is disposable, while the base class isn't
So, are there any alternative concepts/approaches for properly releasing such resources? Any papers/research in that direction?
One approach (in languages that support it) is to manually trigger a garbage collection event to cause finalizers to run. However, some languages (like Java) do not provide a reliable mechanism for doing so.

Avoid COM marshalling

I'm a little confused about com threading models.
I have an inproc server and I want to create an interface accesible from any thread regardless of the threading-model and/or flags used in CoInitializeEx.
When passing interfaces from one thread to another I use CoMarshalInterface/CoUnmarshalInterface without problems but I want to know if exists any way to avoid that and directly pass the interface pointer.
I tried making the interface use neutral apartment but still have to call CoMarshalInterface/CoUnmarshalInterface to avoid problems.
Regards,
Mauro.
COM objects reside in one apartment only. Accessing a COM object via an interface pointer across apartment boundaries is never a good idea unless you're applicable scenario can utilize a free threaded marshaling aggregate. A free-threaded marshaller, essentially says that all clients of this interface, regardless of apartment and thread, are in the same process and will rely on the object itself to maintain synchronization and thread safety. The object itself must aggregate the free-threaded marshaller interface, so hopefully you're the author of it as well as the client code.
More information on free-threaded marshaling can be found at msdn.com, but one of their articles covering the object I tend to reuse again and again is this one.
I hope it helps you out.

How to access COM objects from different apartment models?

I have a multi-threaded C++Builder GUI app, which communicates with a third-party app via COM.
I need to call methods of the COM object from several threads, and I'm protecting access with a mutex. Apparently, the main GUI thread must use STA model, but my worker threads need to use MTA. The COM object is constructed in an MTA thread.
Everything works fine except access to the COM object from the GUI thread, due to the MTA/STA mismatch.
I've read a bit about marshalling, but haven't tried to implement it, because the examples I've seen seem to require different access semantics depending the the current apartment model, and I really would like to have code that (from a programmer's POV) doesn't care about the current apartment model.
So, is there an idiomatic way to write COM code that operates on the 'same' object, but can be called from both STA and MTA threads?
Put the COM object interface into the Global Interface Table and let the GIT handle the marshalling for you. When any thread requests the COM interface, the GIT checks the calling apartment and will provide a direct pointer or a suitable proxy accordingly. Your code won't know the difference (or care), just use the returned interface normally as needed.
This is documented on MSDN:
Accessing Interfaces Across Apartments

Should a managed class that wraps a DirectSound interface be IDisposable?

I'm writing a managed wrapper around DirectSound. (It's a simple partial wrapper that solves my specific problem and nothing more. Don't tell me about NAudio or whatever.) Should a managed class that wraps IDirectSound8 be IDisposable and why? Same question about IDirectSoundBuffer8.
Technically: yes. Practically: no. IDirectSound8 is a COM interface, they are very conveniently wrapped in .NET with a interop library. An RCW. That RCW manages the reference counts on the underlying COM coclass object. An RCW does not implement IDisposable, even though it very much hangs on to an unmanaged resource.
The reason it doesn't is because it is almost impossible to implement IDisposable correctly. A COM coclass implements multiple interfaces, creating one adds to the reference count. You would have to be 100% sure that all of those interface pointers are no longer in use before a dispose would be safe. That's very hard to do, those pointers get created in unexpected ways. Like using an indexed property of one of the interfaces, the intermediate interface pointer is never visible in your code.
This is not a real problem, the garbage collector takes care of the reference counts, the finalizer gets the job done. It is just that it takes a bit longer for the object to be released. Standard GC behavior. Unfortunately out-of-process COM servers have observable side-effects, programmers tend to get annoyed when the process doesn't disappear from the TaskMgr processes list at the instant their code stops using the interfaces. Many, many "Excel/Word doesn't quit" questions here and at the forums.
If you want to implement it anyway then you can do so by calling Marshal.FinalReleaseComObject() in your Dispose() implementation. Just beware of the significantly increased risk for failure, getting that call wrong produces very hard to diagnose failure. Not quite unlike deleting an object in native code and still having a pointer to it. If it is actually a "heavy" object that must be released instantly then GC.Collect() + GC.WaitForPendingFinalizers() gets the job done too with much less risk of getting it wrong. With side-effects of course.