DCOM Explained
by Rosemary Rock-Evans
Digital Press
ISBN: 1555582168   Pub Date: 09/01/98

Previous Table of Contents Next


Chapter 9
Other Communication Functions

  Triggering
  Context Bridging
  Broadcast and Multicast

MS RPC and Cedar provide specialized services related specifically to the transport of invocations across the network. There are other services, however, that we might loosely think of as services that help in communication, but that are not part of either MS RPC or Cedar.

In this chapter we will look at these functions, what they do, and how they work.

Some are automatically provided for the developer by DCOM—such as context bridging. Some are provided automatically but require developer involvement—such as triggering, and some are services the developer can use to help him or her write component-based applications such as multicasting Where the developer is involved, however, all these services are accessed via the same COM interface.

Triggering

Components in DCOM can be running permanently in memory—loaded and waiting to be used—or they can be stored somewhere in a library. Where they are stored in a library, when a request is made for them, they need to be loaded into memory and started. This latter process is termed “triggering,” and DCOM is able to trigger components.

The advantages of triggering are that if the developer has literally thousands of components to use on a machine, he or she can save memory by storing them on disk and only triggering them when needed. This aspect is especially useful if you only have a small machine—it makes better use of the small amount of memory you may have available, while at the same time still providing a client process with a rich array of functionality.


Figure 9.1  Other communication services

The disadvantage with triggering is that it is slow. To load a component from a library takes time, so if you need a fast response, triggering may not be such a good idea. This is the reason many Distributed Transaction Processing Monitors such as TOP END and Tuxedo do not support triggering—a slow transaction processing application just wouldn’t “cut the mustard” as we techies say! In fact, transaction processing and triggering are incompatible.

Microsoft, however, does provide you with the choice. You can decide to have servers permanently running in memory or, if the server is not running (that is, it exists in the library but not as a running task), DCOM will trigger the server by automatically creating an instance of the server. Thus servers/objects are triggered automatically by DCOM.

But the programmer does have some work to do. DCOM must be directed to create an instance using the Class Factory (we will be learning more about this in the chapter on the Directory), and the programmer has to keep a count of the instances. So how does he or she do this?

As part of the process of creating the instance, the client is passed back a pointer to the IUnknown interface. All objects “inherit” (in reality share methods with) the IUnknown interface. This interface uses two methods which must be called by every client as they use the object instantiated by DCOM. In other words, a count is kept for each object in a server, not of the server. The client must call the methods each time it uses a new interface pointer on the object.


Figure 9.2  DCOM keeps a count of the numbered instances of objects

When the client calls the object it calls the AddRef method. This method increments a reference counter maintained by DCOM, which keeps a count of how many clients are using the object. When the client stops using the object, it must call the Release method. The Release method decrements the same counter.

For example, when a client first creates an object, it receives back an interface pointer to an object that, from the client’s point of view, has a reference count of one. If the client then obtains another interface pointer to the same object, the reference count is two. The client must release through both pointers to decrement the reference count to zero before the object as a whole can release itself. In effect, every copy of any pointer to an interface requires a reference count on it.

In the simplified case, AddRef must be called for every new copy of an interface pointer and Release called every time an interface pointer is destroyed, but more complex rules can apply so that addref and release actions are properly paired and the object is not released before all the methods called have been actioned. (Clearly a wrong action could cause a code crash.) For example, when a global variable is used, it must be independently counted, as calling functions might destroy the copy in global memory while the local copy was still alive. Nested and staggered/overlapping pointer lifetimes or backpointers also have to be carefully managed.


Figure 9.3  Counting is done through interfaces

Clearly, there is the potential here for the counter to get out of step with reality if the client fails, the line goes down between client and server, or the client simply does not respond. We saw that DCOM uses a pinging protocol to detect if clients are still “alive” in a connection. DCOM considers a connection broken if more than three ping periods pass without the components’s receiving a ping message.

If the connection is broken between a client and a server, DCOM automatically decrements the reference count, which keeps track of how many clients are connected.

The treatment of the server, as opposed to the objects “encapsulated” by the server, is different. When a server has no objects to serve, no locks, and is not being controlled by an end user, then the server unloads itself.

The way this is done differs depending on whether the server is an EXE or a DLL.

DLLs wait for “someone else” to explicitly unload them, and the server tells this someone else it can be unloaded via a function that must be coded by the developer—DIICanUnloadNow. EXEs unload themselves by terminating.


Previous Table of Contents Next