How can a COM local server keep itself alive even though there are no active clients?


Suppose you have a COM local server, which means that the COM object is provided by a process different from the clients. And suppose you have a method which triggers some sort of background operation, and the rule for your object is that even if all references to the object are released, the background operation must still run to completion. (This is the model followed by Windows Runtime objects, for example. An asynchronous operation will continue to run independently of the object which initiated the operation.)

The question, then, is how to communicate to the COM infrastructure that you are still doing work and the server should not be shut down just because there are no outstanding references to it.

Assuming the object is MTA-threaded or free-threaded, the recommendation for out-of-process servers is to use Co­Add­Ref­Server­Process and Co­Release­Server­Process to manage their process lifetime. In particular, Co­Release­Server­Process will automatically call Co­Suspend­Class­Objects when the process reference count reaches zero, thereby avoiding the race condition where one thread drops the reference count to zero, and before it can call Co­Suspend­Class­Objects, another thread sneaks in and creates an object.

I'm not the subject matter expert here, so I'll leave you with some fascinating reading on the subject.

  • This article discusses the issue at hand and covers many of the race conditions that can occur.
  • This article is a more general discussion of free-threaded COM objects.

Warning: Both articles were originally magazine articles, and the tall narrow formatting is carried over to the Web presentation.

Comments (8)
  1. SI says:

    We ran into a similar but more insidious problem? A COM local server hands out references to an object(A) which in turn can create in-proc objects and hand out references to those (B). If the client process then releases the main object(A) the server process shuts down even though it is still hosting the subobject B.

    Ideally the server process would call CoAddRefServerProcess for every loaded COM DLL that isn’t ready to be freed, but I never figured out how CoFreeUnusedLibrariesEx enumerates the DLLs.

  2. Mike Dimmick says:

    I suspect the tall narrow formatting may have more to do with the screen sizes that were common 20 years ago! It looks perfectly fine at 640×480 or 800×600. There’s also the widely-held belief that it’s easier to scan shorter lines, e.g. http://baymard.com/blog/line-length-readability, http://practicaltypography.com/line-length.html, or http://www.webstyleguide.com/wsg2/type/lines.html which is of a similar era (ironically, it doesn’t limit the text width!) The articles are about 50-55 characters per line. We’ve just got used to ludicrously wide layouts due to web pages that pay no attention to page width, particularly on widescreen monitors.

    Developers are probably more used to very wide layouts. I’m struggling to keep my juniors within the width that renders without wrapping in GitLab’s Merge Request view with both sidebars open, on a widescreen 1920×1080 monitor (about 120 columns).

    1. Lars Viklund says:

      The term “magazine” is used for a reason. MSJ existed as a physical dead-tree artifact, whose articles had the typical narrow column typesetting.

      I guess you could say that the online archives are skeumorphic.

  3. It’s pretty cool that COM has been solid and stable enough that a 20-year-old article is still authoritative.

  4. Ken Hagan says:

    SI: That’s a scenario you can get with OLE linking to embeddings. It is solved in that case by insisting that object B offers a way to obtain the IOleContainer interface on A, so that its clients can call LockContainer.

  5. Ken Hagan says:

    …or have I mis-remembered and this is the occasion where we reach for IExternalConnection?

    1. SI says:

      I’ll read up on both of those and see if either one helps, thanks.

  6. Mark says:

    You are my hero. Thank you for posting this for me and the five other people still interested in COM development.

    I am actually working on a distributed algorithm research project using DCOM and was considering an approach to trick out remote COM servers on their internal client count in order to exert some control over their startup/shutdown process – rather than implement them (and register them) as full Windows services.

Comments are closed.

Skip to main content