summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkirthika <kirthika@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-12-31 09:44:16 +0000
committerkirthika <kirthika@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-12-31 09:44:16 +0000
commitf85da069ec265ce8835491099021fff4c1e40708 (patch)
treee777eeab89348736dc52c8ac7c4e87ccd42fc6d8
parentf9e95c533c96377053925203330fdd65b06a9687 (diff)
downloadATCD-f85da069ec265ce8835491099021fff4c1e40708.tar.gz
*** empty log message ***
-rw-r--r--TAO/examples/POA/Loader/README60
-rw-r--r--TAO/examples/POA/Loader/Servant_Activator.cpp96
-rw-r--r--TAO/examples/POA/Loader/Servant_Locator.cpp108
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);
+}
+