diff options
author | kirthika <kirthika@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-12-31 09:44:16 +0000 |
---|---|---|
committer | kirthika <kirthika@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-12-31 09:44:16 +0000 |
commit | f85da069ec265ce8835491099021fff4c1e40708 (patch) | |
tree | e777eeab89348736dc52c8ac7c4e87ccd42fc6d8 | |
parent | f9e95c533c96377053925203330fdd65b06a9687 (diff) | |
download | ATCD-f85da069ec265ce8835491099021fff4c1e40708.tar.gz |
*** empty log message ***
-rw-r--r-- | TAO/examples/POA/Loader/README | 60 | ||||
-rw-r--r-- | TAO/examples/POA/Loader/Servant_Activator.cpp | 96 | ||||
-rw-r--r-- | TAO/examples/POA/Loader/Servant_Locator.cpp | 108 |
3 files changed, 264 insertions, 0 deletions
diff --git a/TAO/examples/POA/Loader/README b/TAO/examples/POA/Loader/README new file mode 100644 index 00000000000..db78c9c5df6 --- /dev/null +++ b/TAO/examples/POA/Loader/README @@ -0,0 +1,60 @@ +$Id$ + +Loader Example +-------------- + +This example illustrates how to dynamically link and load servants +into a POA in a platform-independent manner using the ACE_DLL feature +and standard CORBA Servant Manager features. In the example, the POA +is configured with the USE_SERVANT_MANAGER policy value, which relies +on an application supplied Servant Manager object to supply +object/server associations. + +If the POA has the RETAIN value for the servant retention, the POA +expects the Servant Manager to implement the Servant Activator +interface. Conversely, when the POA is created with the NON_RETAIN +value for servant retention, the Servant Manager must implement the +Servant_Locator interface. + +This example illustrates both Servant Activator and Servant_Locator +interfaces. The servant object is created by a factory function that +resides in a DLL that is linked and loaded into the server's address +space on-demand when client requests arrive. The ObjectID in each +client request indicates which DLL name and which factory function to +use to create the servant. + +For the Servant_Activator example, once the servant is loaded, the +Object-to-Servant association is added to the Active Object Map +maintained by the POA. This association becomes invalid when the POA +is destroyed or/and the Object is deactivated. In contrast, for the +Servant_Locator example operation request from the client causes the +servant to be linked, processed, destroyed, and unlinked. + +For all examples, the dynamic configuration granularity is at the POA +level,i.e., a Servant Activator or Servant Locator is associated with +a DLL that is linked and loaded into memory and servant objects +obtained on-demand. The factory function within the DLL decides the +servant to be supplied based on the ObjectId and supplies the +appropriate servant to the Servant Manager interface. Theres also an +providence made for an garbage_collection function which can be used +to destroy the servant. Both the factory function as well as the +garbage collection function can be implemented by the application +developer in the preferred manner. + +Note that the server need not be statically linked with the DLL. The +DLL name and the factory function used to obtain the servant can be +provided to the server at run-time. This gives us the flexibility of +modifying and linking the servant without having to statically link +the server along with the DLL. + +Execution: +--------- + + Run the run_test_pl perl script. + +example: + run_test_pl -f ior_file + +The output will demonstrate the different actions performed by the +Servant_Manager via the Servant_Activator and the Servant_Locator +interfaces. diff --git a/TAO/examples/POA/Loader/Servant_Activator.cpp b/TAO/examples/POA/Loader/Servant_Activator.cpp new file mode 100644 index 00000000000..fe17d1feef7 --- /dev/null +++ b/TAO/examples/POA/Loader/Servant_Activator.cpp @@ -0,0 +1,96 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/examples/POA/Loader +// +// = FILENAME +// Servant_Activator.cpp +// +// = DESCRIPTION +// Implementation of <ServantActivator_i>, which is used by a POA +// with a RETAIN policy. +// +// = AUTHOR +// Kirthika Parameswaran <kirthika@cs.wustl.edu> +// +// ============================================================================ + +#include "Servant_Activator.h" +#include "MyFooServant.h" + +ACE_RCSID(Loader, Servant_Activator, "$Id$") + +// Initialization.The dllname is used by the Loactor to load it into +// memory. The factory function is the point of entry into the dll and +// is used for obtaining the servant. The garbage_collection_function +// is used to kill the servant. + +ServantActivator_i::ServantActivator_i (CORBA::ORB_ptr orb, + const char *dllname, + const char *factory_function, + const char *garbage_collection_function) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ + // The dll is opened using the dllname passed. + if (this->dll_.open (dllname) == -1) + ACE_ERROR ((LM_ERROR, + "%p", + this->dll_.error ())); + + + // Obtain the symbol for the function that will + // get the servant object. + servant_supplier_ = ACE_reinterpret_cast + (SERVANT_FACTORY, this->dll_.symbol (factory_function)); + + // Obtain tne symbol for the function which + // will destroy the servant. + servant_garbage_collector_ = ACE_reinterpret_cast + (SERVANT_GARBAGE_COLLECTOR, this->dll_.symbol (garbage_collection_function)); + +} + +// This method associates an servant with the ObjectID. + +PortableServer::Servant +ServantActivator_i::incarnate (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + CORBA::Environment &env) +{ + // Obtain the servant else exception. + PortableServer::Servant servant = + (*servant_supplier_) (oid, + poa, + this->orb_.in ()); + if (servant != 0) + return servant; + else + TAO_THROW_ENV_RETURN (CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO), + env, + 0); +} + +// This is the method invoked when the object is deactivated or the +// entire POA is is deactivated or destroyed. + +void +ServantActivator_i::etherealize (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + PortableServer::Servant servant, + CORBA::Boolean, + CORBA::Boolean remaining_activations, + CORBA::Environment &) +{ + // If there are no remaining activations i.e ObjectIds associated + // with MyFooServant object, deactivate it by calling the garbage_collection_function. + // Etheralization happens on POA::destroy() and/or Object::deactivate(). + + if (remaining_activations == 0) + (*servant_garbage_collector_) (oid, + poa, + servant); + +} + diff --git a/TAO/examples/POA/Loader/Servant_Locator.cpp b/TAO/examples/POA/Loader/Servant_Locator.cpp new file mode 100644 index 00000000000..f059e2952fb --- /dev/null +++ b/TAO/examples/POA/Loader/Servant_Locator.cpp @@ -0,0 +1,108 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO/examples/POA/Loader +// +// = FILENAME +// Servant_Locator.cpp +// +// = DESCRIPTION +// Implementation of ServantLocator_i class, used with a POA +// having a NON_RETAIN policy. +// +// = AUTHOR +// Kirthika Parameswaran <kirthika@cs.wustl.edu> +// +// ============================================================================ + +#include "Servant_Locator.h" +#include "MyFooServant.h" + +ACE_RCSID(Loader, Servant_Locator, "$Id$") + +// Initialization.The dllname is used by the Loactor to load it into +// memory. The factory function is the point of entry into the dll and +// is used for obtaining the servant. The garbage_collection_function +// is used to kill the servant. + +ServantLocator_i::ServantLocator_i (CORBA::ORB_ptr orb, + const char *dllname, + const char *factory_function, + const char *garbage_collection_function) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ + // The dll is opened using the dllname passed. + if (this->dll_.open (dllname) == -1) + ACE_ERROR ((LM_ERROR, + "%p", + this->dll_.error ())); + + // Obtain the symbol for the function that will + // get the servant object. + servant_supplier_ = ACE_reinterpret_cast + (SERVANT_FACTORY, this->dll_.symbol (factory_function)); + + // Obtain tne symbol for the function which + // will destroy the servant. + servant_garbage_collector_ = ACE_reinterpret_cast + (SERVANT_GARBAGE_COLLECTOR, this->dll_.symbol (garbage_collection_function)); + +} + +// This method associates an servant with the ObjectID. + +PortableServer::Servant +ServantLocator_i::preinvoke (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa, + const char * /* operation */, + PortableServer::ServantLocator::Cookie &cookie, + CORBA::Environment &env) +{ + PortableServer::Servant servant = + (*servant_supplier_) (oid, + poa, + this->orb_.in ()); + if (servant != 0) + { + // Return the servant as the cookie , used as a check when + // postinvoke is called on this ServantLocator_i. + + cookie = servant; + return servant; + } + else + TAO_THROW_ENV_RETURN (CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO), + env, + 0); +} + +// Since the servant gets invoked per operation, the servant has to be +// destroyed per operation too. This is accomplished in the +// postinvoke method. + +void +ServantLocator_i::postinvoke (const PortableServer::ObjectId &oid, + PortableServer::POA_ptr poa , + const char * /* operation */, + PortableServer::ServantLocator::Cookie cookie, + PortableServer::Servant servant, + CORBA::Environment &/* env */) +{ + // Check the passed servant with the cookie. + PortableServer::Servant my_servant = + ACE_reinterpret_cast (PortableServer::Servant, + cookie); + + ACE_ASSERT (servant == my_servant); + + // Invoke the garbage_collection_function. + (*servant_garbage_collector_) (oid, + poa, + servant); + + // To avoid warning about unused variable with ACE_NDEBUG. + ACE_UNUSED_ARG (my_servant); +} + |