The general idea is to have each server contain a hierarchy of POAs. Only the Root POA is created by default; a reference to the Root POA is obtained using the resolve_initial_references() operation on the ORB. New POAs can be created as the child of an existing POA, each with its own set of policies.
Each POA maintains an Active Object Map that maps all objects that have been activated in the POA to a servant. For each incoming request, the POA looks up the object reference in the Active Object Map and tries to find the responsible servant. If none is found, the request is either delegated to a default servant, or a servant manager is invoked to activate or locate an appropriate servant.
Associated with each POA is a POA Manager object. A POA Manager can control one or many POAs. For each incoming request to an object, the POA Manager's state is checked, which can be one of the following:
Before continuing, we should more precisely define a few terms that have already been freely used.
In many cases, object references and Object Id can be used synonymously, since an object reference is just an Object Id with opaque POA-added ``internal'' information.
The process of associating a servant with an Object Id is called activation and is performed using POA methods. A servant can be activated more than once (to serve many different Object Ids) and can be activated in many POAs. After activation, object references can be obtained using other POA methods.
Servants are not objects and do not inherit from CORBA::Object. It is illegal to perform operations directly upon a servant - all invocations must be routed through the ORB. Also, memory management of servants is entirely left to the user. POAs keep only a pointer to a servant, so they must not be deleted while being activated.