Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced CORBA Programming wit C++ - M. Henning, S. Vinoski.pdf
Скачиваний:
65
Добавлен:
24.05.2014
Размер:
5 Mб
Скачать

IT-SC book: Advanced CORBA® Programming with C++

A POA with a RequestProcessingPolicy value of USE_SERVANT_MANAGER and a ServantRetentionPolicy value of NON_RETAIN dispatches requests exactly as in the preceding scenario except that the POA has no Active Object Map to search. In other words, the servant manager must be a ServantLocator and not a

ServantActivator.

A POA with a RequestProcessingPolicy value of USE_DEFAULT_SERVANT and a ServantRetentionPolicy value of RETAIN searches its Active Object Map for the object ID of the target object. If it does not find it and if a default servant has been registered with the POA, the request is dispatched to it. If the object ID is not in the Active Object Map and if no default servant has been registered with the POA, the POA raises the CORBA::OBJ_ADAPTER system exception.

A POA with a RequestProcessingPolicy value of USE_DEFAULT_SERVANT and a ServantRetentionPolicy value of NON_RETAIN dispatches requests exactly as in the preceding scenario except that the POA has no Active Object Map to search (the servant manager must be a ServantLocator).

11.8 Reference, ObjectId, and Servant

As we describe in Section 11.3.2, many POA operations involve conversions or associations among object references, object IDs, and servants. Not surprisingly, the POA interface provides six helper functions that allow navigation among these three key entities.

module PortableServer { interface POA {

exception ServantNotActive {}; exception WrongPolicy {}; exception ObjectNotActive {}; exception WrongAdapter {};

ObjectId servant_to_id(in Servant serv) raises(ServantNotActive, WrongPolicy);

Object servant_to_reference(in Servant serv) raises(ServantNotActive, WrongPolicy);

Servant reference_to_servant(in Object ref) raises(

ObjectNotActive, WrongAdapter, WrongPolicy

);

ObjectId reference_to_id(in Object ref) raises(WrongAdapter, WrongPolicy);

Servant id_to_servant(in ObjectId oid) raises(ObjectNotActive, WrongPolicy);

Object id_to_reference(in ObjectId oid) raises(ObjectNotActive, WrongPolicy);

// ...

}; // ...

};

436

IT-SC book: Advanced CORBA® Programming with C++

All operations except the reference_to_id and reference_to_servant operations require the target POA to have the RETAIN policy value. Each operation raises the WrongPolicy exception if the target POA does not have the required policies.

The servant_to_id operation returns the ObjectId associated with the target servant. The target POA policies affect the behavior of servant_to_id as follows.

If the target POA has the UNIQUE_ID policy and the servant is already registered in the Active Object Map, the POA returns the associated ObjectId.

If the POA has the IMPLICIT_ACTIVATION and MULTIPLE_ID policy values, the POA implicitly activates a new CORBA object using the servant with a POA-generated object ID, and the POA returns that ID.

Similarly, if the POA has the IMPLICIT_ACTIVATION and UNIQUE_ID policy values and the servant is not yet active, the POA implicitly activates a new CORBA object using the servant with a POA-generated object ID, and the POA returns that ID.

Otherwise, servant_to_id raises the ServantNotActive exception.

If the servant_to_id operation activates the object, it will invoke _add_ref on its servant argument before returning. Otherwise, the POA does not invoke _add_ref or _remove_ref on the servant.

The servant_to_reference operation returns the object reference of the object the servant is incarnating. If the target POA has the IMPLICIT_ACTIVATION and MULTIPLE_ID policy values, the POA implicitly activates a new CORBA object using the servant with a POA-generated object ID, and then it returns the new reference. It also does this if the POA has the IMPLICIT_ACTIVATION and UNIQUE_ID policy values and the servant is not yet active. Otherwise, servant_to_reference raises the

ServantNotActive exception.

If the servant_to_reference operation activates the object, it will invoke _add_ref on its servant argument before returning. Otherwise, the POA does not invoke _add_ref or _remove_ref on the servant.

The reference_to_servant operation returns the servant that incarnates the object referred to by the object reference. The target POA requires either the RETAIN policy value or the USE_DEFAULT_SERVANT policy value. If the object referred to by the object reference has an object-to-servant association in the Active Object Map or if a default servant is registered, that servant is returned. Otherwise, reference_to_servant raises the ObjectNotActive exception.

The caller of reference_to_servant is responsible for invoking _remove_ref once on the returned servant when it is finished using it. However, if the application uses

437

IT-SC book: Advanced CORBA® Programming with C++

only the empty servant reference counting implementations inherited from the PortableServer::ServantBase class, the caller need not invoke _remove_ref under these circumstances. We recommend always invoking _remove_ref in this case, however, to avoid maintenance problems.

The reference_to_id operation returns the object ID from within the object reference argument passed to it. The object referred to by the object reference need not be active for you to invoke this operation. If the target POA did not create the object reference, reference_to_id raises the WrongAdapter exception.

The id_to_reference operation returns an object reference for the object denoted by the object ID argument. If the specified object ID is not found in the Active Object Map, the operation raises the ObjectNotActive exception.

The id_to_servant returns the servant associated with the specified object ID. If the object ID is not found in the Active Object Map, the operation raises the

ObjectNotActive exception.

The caller of id_to_servant is responsible for invoking _remove_ref once on the returned servant when it is finished using it. However, if the application uses only the empty servant reference counting implementations inherited from the PortableServer::ServantBase class, the caller need not invoke _remove_ref under these circumstances. We recommend always invoking _remove_ref in this case, however, to avoid maintenance problems.

You should be aware that C++ servants do not support narrowing, as we explain in Section 11.7.4. This means that the return values of reference_to_servant and id_to_servant cannot be portably down-cast to your derived servant types. If your application requires navigation from either an object reference or an object ID to its associated servant so that you can directly invoke derived servant functions, you must use C++ dynamic_cast to cast the Servant down to the derived type you are looking for. Not all C++ compilers support dynamic_cast, however, so make sure it is available on all platforms where your application must run.

11.9 Object Deactivation

Eventually, all CORBA objects must be deactivated. An object might be deactivated because its server application is shutting down or because someone is destroying the object. As we state in Section 11.3.1, a CORBA object is a virtual entity that can respond to requests only when a servant incarnates it. Deactivation simply makes a CORBA object unable to respond to requests.

Because activating a CORBA object requires you to set up an object-to-servant association, to deactivate an object you break the object-to-servant association. You do this by invoking deactivate_object on the POA hosting the object.

438

IT-SC book: Advanced CORBA® Programming with C++

module PortableServer { interface POA {

exception ObjectNotActive {}; exception WrongPolicy {};

void deactivate_object(in ObjectId oid)

raises(ObjectNotActive, WrongPolicy);

// ...

};

// ...

};

You can invoke deactivate_object only on POAs with the RETAIN value of the

ServantRetentionPolicy. If you invoke it on a NON_RETAIN POA, it raises the

WrongPolicy exception. In a way, you can view the deactivate_object method as a kind of administrative tool for helping you control the contents of a POA's Active Object Map.

To deactivate an object, you invoke deactivate_object on the object's POA, passing the ObjectId of the object as the only argument. This eventually causes the POA to remove the ObjectId-to-servant association from its Active Object Map once there are no more active requests for that ObjectId. If the application had previously registered a ServantActivator with the POA, the POA invokes the etherealize method of the ServantActivator for the deactivated object's servant. This allows the application to take actions to clean up the servant, such as invoking _remove_ref on the servant or calling delete on it. The POA guarantees that it will not access the servant in any way after it passes it to etherealize. Otherwise, if the application did not supply a ServantActivator, the POA invokes _remove_ref on the servant after all method calls on it have completed.

An important detail of the deactivate_object operation is that it returns immediately without waiting for the actual object deactivation to take place. This is because the POA does not remove the object's servant from its Active Object Map until all requests on the target object have completed. If the operation instead waited for all requests on the object to complete, a deadlock situation might occur. Assume that an object supports a destroy operation that destroys the target object when invoked. If the implementation of destroy invoked deactivate_object and if deactivate_object in turn waited until all requests in progress on the object's servant completed, the operation would never finish because deactivate_object would be deadlocked waiting on the destroy method that invoked it. To avoid the potential for deadlock, deactivate_object simply marks the Active Object Map entry for deactivation and returns immediately.

After an object is deactivated, it can be reactivated if the application allows it. Should a new request arrive for an object that has been deactivated, the POA attempts to locate an

439