Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / CSD_Strategy / ThreadPool3 / ServerApp.cpp
blobaee9cea9cfe85c663b9521496f258a3d3df2fde8
1 #include "ServerApp.h"
2 #include "Foo_i.h"
3 #include "OrbTask.h"
4 #include "OrbShutdownTask.h"
5 #include "ace/Get_Opt.h"
6 #include "tao/CSD_ThreadPool/CSD_TP_Strategy.h"
7 #include "tao/Intrusive_Ref_Count_Handle_T.h"
8 // To force static load the service.
9 #include "tao/PI/PI.h"
10 #include "tao/CSD_ThreadPool/CSD_ThreadPool.h"
13 ServerApp::ServerApp()
14 : ior_filename_(ACE_TEXT("ServerApp.default.ior")),
15 num_clients_(1),
16 num_orb_threads_(1)
21 ServerApp::~ServerApp()
26 int
27 ServerApp::run (int argc, ACE_TCHAR* argv[])
29 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
31 // Parse the command-line args for this application.
32 // * Raises -1 if problems are encountered.
33 // * Returns 1 if the usage statement was explicitly requested.
34 // * Returns 0 otherwise.
35 int result = this->parse_args (argc, argv);
36 if (result != 0)
38 return result;
41 TheOrbShutdownTask::instance()->orb (orb.in ());
43 CORBA::Object_var obj
44 = orb->resolve_initial_references("RootPOA");
46 if (CORBA::is_nil(obj.in()))
48 ACE_ERROR((LM_ERROR,
49 "(%P|%t) Failed to resolve initial ref for 'RootPOA'.\n"));
50 throw TestException();
53 PortableServer::POA_var root_poa
54 = PortableServer::POA::_narrow(obj.in());
56 if (CORBA::is_nil(root_poa.in()))
58 ACE_ERROR((LM_ERROR,
59 "(%P|%t) Failed to narrow obj ref to POA interface.\n"));
60 throw TestException();
63 PortableServer::POAManager_var poa_manager
64 = root_poa->the_POAManager();
66 // Create the child POA.
67 CORBA::PolicyList policies(0);
68 policies.length(0);
70 PortableServer::POA_var child_poa
71 = root_poa->create_POA("ChildPoa",
72 poa_manager.in(),
73 policies);
75 if (CORBA::is_nil(child_poa.in()))
77 ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
78 "Failed to create the child POA.\n"));
79 throw TestException();
82 // Create the thread pool servant dispatching strategy object, and
83 // hold it in a (local) smart pointer variable.
84 TAO_Intrusive_Ref_Count_Handle<TAO::CSD::TP_Strategy> csd_tp_strategy =
85 new TAO::CSD::TP_Strategy();
87 // Tell the strategy to apply itself to the child poa.
88 if (csd_tp_strategy->apply_to(child_poa.in()) == false)
90 ACE_ERROR((LM_ERROR, "(%P|%t) ERROR [ServerApp::run()]: "
91 "Failed to apply custom dispatching strategy to child poa.\n"));
92 throw TestException();
95 // Create the servant object.
96 Foo_i* servant = new Foo_i(this->num_clients_);
98 // local smart pointer variable to deal with releasing the reference
99 // to the servant object when the smart pointer object falls out of scope.
100 PortableServer::ServantBase_var owner_transfer(servant);
102 // Activate the servant using the Child POA.
103 PortableServer::ObjectId_var oid
104 = child_poa->activate_object(servant);
106 // Obtain the object reference.
107 obj = child_poa->servant_to_reference(servant);
109 if (CORBA::is_nil(obj.in()))
111 ACE_ERROR((LM_ERROR,
112 "(%P|%t) Failed to activate servant (Foo_i).\n"));
113 throw TestException();
116 // Stringify the object reference
117 CORBA::String_var ior
118 = orb->object_to_string(obj.in());
120 // Write the stringified object reference to the ior file.
121 FILE* ior_file = ACE_OS::fopen(this->ior_filename_.c_str(), "w");
123 if (ior_file == 0)
125 ACE_ERROR((LM_ERROR,
126 "(%P|%t) Cannot open output file for writing IOR: %s",
127 this->ior_filename_.c_str()));
128 throw TestException();
131 ACE_OS::fprintf(ior_file, "%s", ior.in ());
132 ACE_OS::fclose(ior_file);
134 // Activate the POA Manager
135 poa_manager->activate();
137 ACE_DEBUG((LM_DEBUG,
138 "(%P|%t) ServerApp is ready.\n"));
140 // If the num_orb_threads_ is exactly one, then just use the current
141 // (mainline) thread to run the ORB event loop.
142 if (this->num_orb_threads_ == 1)
144 // Since the num_orb_threads_ is exactly one, we just use the current
145 // (mainline) thread to run the ORB event loop.
146 orb->run();
148 else
150 // The num_orb_threads_ is greater than 1, so we will use an OrbTask
151 // (active object) to run the ORB event loop in (num_orb_threads_ - 1)
152 // threads. We use the current (mainline) thread as the other thread
153 // running the ORB event loop.
154 OrbTask orb_task(orb.in(), this->num_orb_threads_ - 1);
156 // Activate the OrbTask worker threads
157 if (orb_task.open() != 0)
159 ACE_ERROR((LM_ERROR,
160 "(%P|%t) Failed to open the OrbTask.\n"));
161 throw TestException();
164 // This will use the current (mainline) thread to run the ORB event loop.
165 orb->run();
167 // Now that the current thread has unblocked from running the orb,
168 // make sure to wait for all of the worker threads to complete.
169 orb_task.wait();
172 ACE_DEBUG((LM_DEBUG,
173 "(%P|%t) ServerApp is waiting for OrbShutdownTask.\n"));
174 TheOrbShutdownTask::instance()->wait ();
176 // Sleep for 2 second to let the done() two-way call complete
177 // before cleanup.
178 ACE_OS::sleep (2);
180 // Tear-down the root poa and orb.
181 root_poa->destroy(1, 1);
182 orb->destroy();
184 return 0;
189 ServerApp::parse_args(int argc, ACE_TCHAR* argv[])
191 this->exe_name_ = argv[0];
193 ACE_Get_Opt get_opts(argc, argv, ACE_TEXT("o:n:t:"));
195 int c;
196 int tmp;
198 while ((c = get_opts()) != -1)
200 switch (c)
202 case 'o':
203 this->ior_filename_ = get_opts.opt_arg();
204 break;
206 case 'n':
207 tmp = ACE_OS::atoi(get_opts.opt_arg());
208 if (tmp < 1)
210 this->usage_statement();
211 return -1;
214 this->num_clients_ = tmp;
215 break;
217 case 't':
218 tmp = ACE_OS::atoi(get_opts.opt_arg());
219 if (tmp < 1)
221 this->usage_statement();
222 return -1;
225 this->num_orb_threads_ = tmp;
226 break;
227 case '?':
228 this->usage_statement();
229 return 1;
231 default:
232 this->usage_statement();
233 return -1;
237 return 0;
241 void
242 ServerApp::usage_statement()
244 ACE_ERROR((LM_ERROR,
245 "Usage: %s [options]\n\n"
246 "OPTIONS:\n\n"
247 "\t[-o <ior_filename>]\n"
248 "\t[-n <num_clients>]\n"
249 "\t[-t <num_orb_threads>]\n"
250 "\t[-?]\n",
251 "Default ior_filename_prefix is 'foo'.\n"
252 "Default num_servants is 1.\n"
253 "Default num_clients is 1.\n\n",
254 this->exe_name_.c_str()));