summaryrefslogtreecommitdiff
path: root/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp')
-rw-r--r--TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp
new file mode 100644
index 00000000000..6ec34ef4561
--- /dev/null
+++ b/TAO/examples/CSD_Strategy/ThreadPool5/FooServantList.cpp
@@ -0,0 +1,213 @@
+// $Id$
+#include "FooServantList.h"
+#include "Foo_i.h"
+#include "Callback_i.h"
+#include "ClientTask.h"
+#include "OrbShutdownTask.h"
+#include "ace/OS.h"
+
+
+FooServantList::FooServantList(const char* prefix,
+ unsigned num_servants,
+ unsigned num_clients,
+ int collocated_test,
+ int servant_to_deactivate,
+ CORBA::ORB_ptr orb)
+ : prefix_(prefix),
+ num_servants_(num_servants),
+ num_clients_(num_clients),
+ init_num_clients_ (num_clients_),
+ collocated_test_(collocated_test),
+ servant_to_deactivate_ (servant_to_deactivate),
+ collocated_client_ (0),
+ orb_ (CORBA::ORB::_duplicate(orb))
+{
+ this->servants_ = new Foo_i* [num_servants];
+ this->safe_servants_ = new PortableServer::ServantBase_var[num_servants];
+}
+
+
+FooServantList::~FooServantList()
+{
+ delete [] this->safe_servants_;
+ delete [] this->servants_;
+ delete collocated_client_;
+}
+
+
+void
+FooServantList::create_and_activate(CORBA::ORB_ptr orb,
+ PortableServer::POA_ptr poa)
+{
+ poa_ = PortableServer::POA::_duplicate (poa);
+
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ char buf[32];
+ ACE_OS::sprintf(buf, "%02d", i + 1);
+ ACE_CString servant_name = this->prefix_ + "_" + buf;
+
+ this->servants_[i] = new Foo_i(servant_name.c_str(),this);
+ this->safe_servants_[i] = this->servants_[i];
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId(servant_name.c_str());
+
+ poa->activate_object_with_id(id.in(),
+ this->safe_servants_[i].in());
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name.c_str()));
+ throw TestException();
+ }
+
+ // create the collocated object reference.
+ if (this->collocated_test_ && i == 0)
+ {
+ Foo_var collocated = Foo::_narrow (obj.in ());
+
+ // Create the servant object.
+ Callback_i* servant = new Callback_i ();
+
+ // local smart pointer variable to deal with releasing the reference
+ // to the servant object when the smart pointer object falls out of scope.
+ PortableServer::ServantBase_var safe_servant(servant);
+
+ PortableServer::ObjectId_var id =
+ PortableServer::string_to_ObjectId("callback");
+
+ poa->activate_object_with_id(id.in(), safe_servant.in());
+
+ CORBA::Object_var obj = poa->id_to_reference(id.in());
+
+ if (CORBA::is_nil(obj.in()))
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to activate servant (%s).\n",
+ servant_name.c_str()));
+ throw TestException();
+ }
+
+ Callback_var callback
+ = Callback::_narrow (obj.in ());
+
+ collocated_client_
+ = new ClientTask(orb, collocated.in (), callback.in (), true);
+ if (collocated_client_->open() != 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Failed to open the collocated client.\n"));
+ throw TestException();
+ }
+ }
+
+ CORBA::String_var ior
+ = this->orb_->object_to_string(obj.in());
+
+ ACE_CString filename = servant_name + ".ior";
+ FILE* ior_file = ACE_OS::fopen(filename.c_str(), "w");
+
+ if (ior_file == 0)
+ {
+ ACE_ERROR((LM_ERROR,
+ "(%P|%t) Cannot open output file (%s) for writing IOR.",
+ filename.c_str()));
+ throw TestException();
+ }
+ else
+ {
+ ACE_DEBUG((LM_DEBUG,
+ "(%P|%t) writing IOR to file %s\n",
+ filename.c_str()));
+ }
+ ACE_OS::fprintf(ior_file, "%s", ior.in());
+ ACE_OS::fclose(ior_file);
+ }
+}
+
+
+void
+FooServantList::client_done(void)
+{
+ unsigned num_left;
+
+ {
+ GuardType guard(this->num_clients_lock_);
+ num_left = --this->num_clients_;
+ }
+
+ if (num_left == 0)
+ {
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::client_done: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+}
+
+
+ClientTask*
+FooServantList::collocated_client () const
+{
+ return collocated_client_;
+}
+
+
+void
+FooServantList::deactivate_servant (void)
+{
+ for (unsigned i = 0; i < this->num_servants_; i++)
+ {
+ // To eliminate compiler warning about comparison of signed vs unsigned.
+ int signed_i = i;
+
+ if ((servant_to_deactivate_ == 0 ) ||
+ ((servant_to_deactivate_ > 0) &&
+ (signed_i == servant_to_deactivate_ - 1)))
+ {
+ if (servants_[i]->active())
+ {
+ servants_[i]->active(false);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)FooServantList::deactivate_servant "
+ "deactivate %dth servant \n", i+1));
+
+ PortableServer::ObjectId_var id =
+ poa_->servant_to_id (safe_servants_[i].in ());
+
+ poa_->deactivate_object (id.in ());
+
+ if (this->num_servants_ == 1)
+ {
+ // If there is only one servant and we deactivate it then
+ // all clients will catch exception and we need a way to
+ // shutdown the orb.
+ // Wait for 5 seconds so we can see the requests queued
+ // will be cancelled by deactivate servant.
+ ACE_OS::sleep (5);
+ ACE_DEBUG((LM_DEBUG, "(%P|%t)shutdown ORB\n"));
+ if (TheOrbShutdownTask::instance()->open(0) != 0)
+ {
+ ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::deactivate_servant: "
+ "failed to create orb shutdown thread.\n"));
+ }
+ }
+ else
+ {
+ GuardType guard(this->num_clients_lock_);
+ // The clients that requests this deactivated servant
+ // will catch exception due to the deactivated servant.
+ // We need descrease the num_clients so the alived
+ // servant can be called to shutdown the orb.
+ this->num_clients_ -= this->init_num_clients_/num_servants_;
+ }
+ }
+ }
+ }
+}
+