summaryrefslogtreecommitdiff
path: root/ACE/TAO/tests/POA/Loader/Servant_Locator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/tests/POA/Loader/Servant_Locator.cpp')
-rw-r--r--ACE/TAO/tests/POA/Loader/Servant_Locator.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/ACE/TAO/tests/POA/Loader/Servant_Locator.cpp b/ACE/TAO/tests/POA/Loader/Servant_Locator.cpp
new file mode 100644
index 00000000000..c7c91e02667
--- /dev/null
+++ b/ACE/TAO/tests/POA/Loader/Servant_Locator.cpp
@@ -0,0 +1,122 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO/examples/POA/Loader
+//
+// = FILENAME
+// Servant_Locator.cpp
+//
+// = DESCRIPTION
+// Implementation of ServantLocator class, used with a POA
+// having a NON_RETAIN policy.
+//
+// = AUTHOR
+// Kirthika Parameswaran <kirthika@cs.wustl.edu>
+//
+// ============================================================================
+
+#include "Servant_Locator.h"
+#include "ace/OS_NS_string.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::ServantLocator (CORBA::ORB_ptr orb,
+ const ACE_TCHAR *dllname,
+ const ACE_TCHAR *factory_function,
+ const ACE_TCHAR *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.
+
+ //
+ // Cannot go from void* to function pointer directly. Cast the void*
+ // to long first.
+ //
+ void *symbol = this->dll_.symbol (factory_function);
+#if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
+ int function = reinterpret_cast<int> (symbol);
+#else
+ intptr_t function = reinterpret_cast<intptr_t> (symbol);
+#endif
+
+ servant_supplier_ =
+ reinterpret_cast<SERVANT_FACTORY> (function);
+
+ // Obtain the symbol for the function which will destroy the
+ // servant.
+ symbol = this->dll_.symbol (garbage_collection_function);
+#if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
+ function = reinterpret_cast<int> (symbol);
+#else
+ function = reinterpret_cast<intptr_t> (symbol);
+#endif
+
+ servant_garbage_collector_ =
+ reinterpret_cast<SERVANT_GARBAGE_COLLECTOR> (function);
+}
+
+// This method associates an servant with the ObjectID.
+
+PortableServer::Servant
+ServantLocator::preinvoke (const PortableServer::ObjectId &oid,
+ PortableServer::POA_ptr poa,
+ const char * /* operation */,
+ PortableServer::ServantLocator::Cookie &cookie)
+{
+ 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.
+
+ cookie = servant;
+ return servant;
+ }
+ else
+ throw CORBA::OBJECT_NOT_EXIST ();
+}
+
+// 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::postinvoke (const PortableServer::ObjectId &oid,
+ PortableServer::POA_ptr poa ,
+ const char * /* operation */,
+ PortableServer::ServantLocator::Cookie cookie,
+ PortableServer::Servant servant)
+{
+ // Check the passed servant with the cookie.
+ PortableServer::Servant my_servant =
+ 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);
+}