Basic COM   «Prev  Next»
Lesson 8 In-process COM servers DllCanUnloadNow
Objective Describe what DllCanUnloadNow does.

In-process COM servers DllCanUnloadNow

DllCanUnloadNow Description

Understanding DllCanUnloadNow builds on the reference-counting concepts covered in the previous module and on the information on In-process servers as discussed earlier in this module.

Local/remote Transparency

COM's local/remote transparency isolates the location and activation of a server from the client. A client simply asks for a class factory and, using IClassFactory::CreateInstance, creates instances of a COM object. Recall that COM uses reference counting to manage the lifetime of a COM object. When a COM object, via QueryInterface, "gives away" an interface pointer (i.e., assigns the output pointer parameter to an interface), it increments a reference counter by calling AddRef. The COM client calls Release when it is finished using an interface pointer. Release decrements the reference counter.

Reference counting

Reference counting supports lifetime management of the COM object. A COM server uses reference counts to track active (COM) objects. A server can be unloaded from memory when all its reference counts are 0.
In-process servers provide function DllCanUnloadNow to assist with the unloading process. Periodically, COM will call into DllCanUnloadNow to ask the server if it can be removed from memory.
In DllCanUnloadNow, a server checks all its reference counts and server locks (i.e., set via IClassFactory::LockServer).

How DllCanUnloadNow is implemented

Conceptually, implementing DllCanUnloadNow is simple: Just check the global server-lock counter and each reference counter in each interface within each COM object. For convenience, many developers keep track of all outstanding objects using a global variable. Let us call this g_objcnt.
Whenever a new object is created, g_objcnt is incremented either in IClassFactory::CreateInstance or in the constructor of the C++ class that implements the new COM object. Recall that in IUnknown::Release, we check to see if the reference count goes to 0. If it is 0, we often delete the C++ class, effectively deleting the COM object.
We now decrement g_objcnt either in Release or in the destructor of the C++ class.
g_objcnt acts as a counter for active COM objects. It is incremented in the context of IClassFactory::CreateInstance when a new COM object is created, and it is decremented when the COM object is destroyed. DllCanUnloadNow can now check g_objcnt along with the server-lock count to determine if the server can be unloaded. Following is a typical implementation of DllCanUnloadNow.

//Global Reference Counters
ULONG g_server_locks = 0;
ULONG g_objcnt = 0;

STDAPI DllCanUnloadNow() {
   if (g_server_locks == 0 && g_objcnt == 0) 
         return TRUE;
   return FALSE;

If they are all 0, no COM objects within the server are in use. The server returns TRUE. Upon seeing a non-zero return, COM will unload the in-process server. If any of the reference counts are non-zero or the lock counter is non-zero, the server returns FALSE and COM leaves the server in memory.

dllCanUnloadNow - Exercise

Click the Exercise link below to apply what you have learned about DllCanUnloadNow.
dllCanUnloadNow - Exercise