Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / CSD_Strategy / ThreadPool5 / FooServantList.cpp
blob00a5094793034309b6dabe9ff5bfbd9f26e2d4f1
1 #include "FooServantList.h"
2 #include "Foo_i.h"
3 #include "Callback_i.h"
4 #include "ClientTask.h"
5 #include "OrbShutdownTask.h"
6 #include "ace/OS_NS_unistd.h"
8 FooServantList::FooServantList(const ACE_TCHAR* prefix,
9 unsigned num_servants,
10 unsigned num_clients,
11 int collocated_test,
12 int servant_to_deactivate,
13 CORBA::ORB_ptr orb)
14 : prefix_(prefix),
15 num_servants_(num_servants),
16 num_clients_(num_clients),
17 init_num_clients_ (num_clients_),
18 collocated_test_(collocated_test),
19 servant_to_deactivate_ (servant_to_deactivate),
20 collocated_client_ (0),
21 orb_ (CORBA::ORB::_duplicate(orb))
23 this->servants_ = new Foo_i* [num_servants];
24 this->safe_servants_ = new PortableServer::ServantBase_var[num_servants];
28 FooServantList::~FooServantList()
30 delete [] this->safe_servants_;
31 delete [] this->servants_;
32 delete collocated_client_;
36 void
37 FooServantList::create_and_activate(CORBA::ORB_ptr orb,
38 PortableServer::POA_ptr poa)
40 poa_ = PortableServer::POA::_duplicate (poa);
42 for (unsigned i = 0; i < this->num_servants_; i++)
44 ACE_TCHAR buf[32];
45 ACE_OS::sprintf(buf, ACE_TEXT("%02d"), i + 1);
46 ACE_TString servant_name = this->prefix_ + ACE_TEXT("_") + buf;
48 this->servants_[i] = new Foo_i(ACE_TEXT_ALWAYS_CHAR(servant_name.c_str()),this);
49 this->safe_servants_[i] = this->servants_[i];
51 PortableServer::ObjectId_var id =
52 PortableServer::string_to_ObjectId(ACE_TEXT_ALWAYS_CHAR(servant_name.c_str()));
54 poa->activate_object_with_id(id.in(),
55 this->safe_servants_[i].in());
57 CORBA::Object_var obj = poa->id_to_reference(id.in());
59 if (CORBA::is_nil(obj.in()))
61 ACE_ERROR((LM_ERROR,
62 "(%P|%t) Failed to activate servant (%s).\n",
63 servant_name.c_str()));
64 throw TestException();
67 // create the collocated object reference.
68 if (this->collocated_test_ && i == 0)
70 Foo_var collocated = Foo::_narrow (obj.in ());
72 // Create the servant object.
73 Callback_i* servant = new Callback_i ();
75 // local smart pointer variable to deal with releasing the reference
76 // to the servant object when the smart pointer object falls out of scope.
77 PortableServer::ServantBase_var safe_servant(servant);
79 PortableServer::ObjectId_var id =
80 PortableServer::string_to_ObjectId("callback");
82 poa->activate_object_with_id(id.in(), safe_servant.in());
84 CORBA::Object_var obj = poa->id_to_reference(id.in());
86 if (CORBA::is_nil(obj.in()))
88 ACE_ERROR((LM_ERROR,
89 "(%P|%t) Failed to activate servant (%s).\n",
90 servant_name.c_str()));
91 throw TestException();
94 Callback_var callback
95 = Callback::_narrow (obj.in ());
97 collocated_client_
98 = new ClientTask(orb, collocated.in (), callback.in (), true);
99 if (collocated_client_->open() != 0)
101 ACE_ERROR((LM_ERROR,
102 "(%P|%t) Failed to open the collocated client.\n"));
103 throw TestException();
107 CORBA::String_var ior
108 = this->orb_->object_to_string(obj.in());
110 ACE_TString filename = servant_name + ACE_TEXT(".ior");
111 FILE* ior_file = ACE_OS::fopen(filename.c_str(), "w");
113 if (ior_file == 0)
115 ACE_ERROR((LM_ERROR,
116 "(%P|%t) Cannot open output file (%s) for writing IOR.",
117 filename.c_str()));
118 throw TestException();
120 else
122 ACE_DEBUG((LM_DEBUG,
123 "(%P|%t) writing IOR to file %s\n",
124 filename.c_str()));
126 ACE_OS::fprintf(ior_file, "%s", ior.in());
127 ACE_OS::fclose(ior_file);
132 void
133 FooServantList::client_done(void)
135 unsigned num_left;
138 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->num_clients_lock_);
139 num_left = --this->num_clients_;
142 if (num_left == 0)
144 if (TheOrbShutdownTask::instance()->open(0) != 0)
146 ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::client_done: "
147 "failed to create orb shutdown thread.\n"));
153 ClientTask*
154 FooServantList::collocated_client () const
156 return collocated_client_;
160 void
161 FooServantList::deactivate_servant (void)
163 for (unsigned i = 0; i < this->num_servants_; i++)
165 // To eliminate compiler warning about comparison of signed vs unsigned.
166 int signed_i = i;
168 if ((servant_to_deactivate_ == 0 ) ||
169 ((servant_to_deactivate_ > 0) &&
170 (signed_i == servant_to_deactivate_ - 1)))
172 if (servants_[i]->active())
174 servants_[i]->active(false);
175 ACE_DEBUG((LM_DEBUG, "(%P|%t)FooServantList::deactivate_servant "
176 "deactivate %dth servant\n", i+1));
178 PortableServer::ObjectId_var id =
179 poa_->servant_to_id (safe_servants_[i].in ());
181 poa_->deactivate_object (id.in ());
183 if (this->num_servants_ == 1)
185 // If there is only one servant and we deactivate it then
186 // all clients will catch exception and we need a way to
187 // shutdown the orb.
188 // Wait for 5 seconds so we can see the requests queued
189 // will be cancelled by deactivate servant.
190 ACE_OS::sleep (5);
191 ACE_DEBUG((LM_DEBUG, "(%P|%t)shutdown ORB\n"));
192 if (TheOrbShutdownTask::instance()->open(0) != 0)
194 ACE_ERROR((LM_ERROR, "(%P|%t)FooServantList::deactivate_servant: "
195 "failed to create orb shutdown thread.\n"));
198 else
200 ACE_GUARD (TAO_SYNCH_MUTEX, ace_mon, this->num_clients_lock_);
201 // The clients that requests this deactivated servant
202 // will catch exception due to the deactivated servant.
203 // We need descrease the num_clients so the alived
204 // servant can be called to shutdown the orb.
205 this->num_clients_ -= this->init_num_clients_/num_servants_;