Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / orbsvcs / Event_Service / Event_Service.cpp
blob29726be0784472383dee0ca1dd57766534f7c9fb
1 #include "orbsvcs/Log_Macros.h"
2 #include "Event_Service.h"
4 #include "ace/Get_Opt.h"
5 #include "ace/Auto_Ptr.h"
6 #include "ace/Argv_Type_Converter.h"
7 #include "ace/OS_main.h"
8 #include "ace/OS_NS_unistd.h"
10 #include "orbsvcs/Daemon_Utilities.h"
12 #include "orbsvcs/CosNamingC.h"
13 #include "orbsvcs/Event_Utilities.h"
14 #include "orbsvcs/Sched/Config_Scheduler.h"
16 #include "orbsvcs/Event/EC_Default_Factory.h"
17 #include "orbsvcs/Event/EC_TPC_Factory.h"
18 #include "orbsvcs/Event/EC_Event_Channel.h"
20 #include "tao/BiDir_GIOP/BiDirGIOP.h"
21 #include "ace/OS_NS_strings.h"
23 int ACE_TMAIN (int argc, ACE_TCHAR* argv[])
25 bool use_thread_per_consumer = false;
26 for(int i = 0; i < argc; i++)
28 if (ACE_OS::strcmp (argv[i], ACE_TEXT ("-a")) == 0)
30 use_thread_per_consumer = true;
31 break;
34 if (use_thread_per_consumer)
35 TAO_EC_TPC_Factory::init_svcs ();
36 else
37 TAO_EC_Default_Factory::init_svcs ();
39 Event_Service event_service;
40 return event_service.run (argc, argv);
43 // ****************************************************************
45 Event_Service::Event_Service (void)
46 : sched_impl_ (0),
47 ec_impl_ (0),
48 scheduler_type_ (ES_SCHED_NONE),
49 use_bidir_giop_ (false),
50 bind_to_naming_service_ (true)
54 Event_Service::~Event_Service (void)
56 delete this->ec_impl_;
57 this->ec_impl_ = 0;
58 delete this->sched_impl_;
59 this->sched_impl_ = 0;
62 int
63 Event_Service::run (int argc, ACE_TCHAR* argv[])
65 try
67 // Check if -ORBDaemon is specified and if so, daemonize at this moment,
68 // -ORBDaemon in the ORB core is faulty, see bugzilla 3335
69 TAO_Daemon_Utility::check_for_daemon (argc, argv);
71 // Initialize ORB.
72 this->orb_ =
73 CORBA::ORB_init (argc, argv);
75 if (this->parse_args (argc, argv) == -1)
76 return 1;
78 CORBA::Object_var root_poa_object =
79 this->orb_->resolve_initial_references("RootPOA");
80 if (CORBA::is_nil (root_poa_object.in ()))
81 ORBSVCS_ERROR_RETURN ((LM_ERROR,
82 " (%P|%t) Unable to initialize the root POA.\n"),
83 1);
85 PortableServer::POA_var root_poa =
86 PortableServer::POA::_narrow (root_poa_object.in ());
88 PortableServer::POAManager_var poa_manager =
89 root_poa->the_POAManager ();
91 poa_manager->activate ();
93 // When we have a service name or a non local scheduler we must use the
94 // naming service.
96 bool use_name_service = bind_to_naming_service_ ||
97 this->scheduler_type_ != ES_SCHED_NONE;
99 CORBA::Object_var naming_obj;
100 RtecScheduler::Scheduler_var scheduler;
101 CosNaming::NamingContext_var naming_context;
103 if (use_name_service)
105 naming_obj=
106 this->orb_->resolve_initial_references ("NameService");
108 if (CORBA::is_nil (naming_obj.in ()))
109 ORBSVCS_ERROR_RETURN ((LM_ERROR,
110 " (%P|%t) Unable to initialize the Naming Service.\n"),
113 naming_context =
114 CosNaming::NamingContext::_narrow (naming_obj.in ());
117 // This is the name we (potentially) register the Scheduling
118 // Service in the Naming Service.
119 CosNaming::Name schedule_name (1);
120 schedule_name.length (1);
121 schedule_name[0].id = CORBA::string_dup ("ScheduleService");
123 // The old EC always needs a scheduler. If none is
124 // specified, we default to a local scheduler
125 if (this->scheduler_type_ == ES_SCHED_LOCAL)
127 // Create a local scheduler instance
128 ACE_NEW_RETURN (this->sched_impl_,
129 ACE_Config_Scheduler,
132 scheduler = this->sched_impl_->_this ();
134 // Register the servant with the Naming Context....
135 if (!CORBA::is_nil (naming_context.in ()))
137 naming_context->rebind (schedule_name, scheduler.in ());
140 else if (this->scheduler_type_ == ES_SCHED_GLOBAL)
142 // Get reference to a scheduler from naming service
143 CORBA::Object_var tmp =
144 naming_context->resolve (schedule_name);
146 scheduler = RtecScheduler::Scheduler::_narrow (tmp.in ());
148 if (CORBA::is_nil (scheduler.in ()))
149 ORBSVCS_ERROR_RETURN ((LM_ERROR,
150 " (%P|%t) Unable to resolve the Scheduling Service.\n"),
154 TAO_EC_Event_Channel_Attributes attr (root_poa.in (),
155 root_poa.in ());
157 if (this->scheduler_type_ != ES_SCHED_NONE)
159 attr.scheduler = scheduler.in ();
162 TAO_EC_Event_Channel* ec_impl = 0;
163 ACE_NEW_RETURN (ec_impl,
164 TAO_EC_Event_Channel (attr),
166 this->ec_impl_ = ec_impl;
168 ec_impl->activate ();
170 RtecEventChannelAdmin::EventChannel_var ec;
172 // If the object_id_ is empty and we don't use BiDIR GIOP, activate the
173 // servant under the default POA, else create a new child POA with
174 // the needed policies
175 int persistent = ACE_OS::strcmp(this->object_id_.c_str(), "");
176 if ((persistent == 0) && (this->use_bidir_giop_ == false))
178 // Notice that we activate *this* object with the POA, but we
179 // forward all the requests to the underlying EC
180 // implementation.
181 ec = this->_this ();
183 else
185 CORBA::ULong index = 0;
187 // Create child POA
188 CORBA::PolicyList policies (3);
190 if (persistent != 0)
192 policies.length (index++);
193 policies[index] =
194 root_poa->create_id_assignment_policy (PortableServer::USER_ID);
196 policies.length (index++);
197 policies[index] =
198 root_poa->create_lifespan_policy (PortableServer::PERSISTENT);
201 if (this->use_bidir_giop_ == true)
203 CORBA::Any pol;
204 pol <<= BiDirPolicy::BOTH;
205 policies.length (index++);
206 policies[index] =
207 this->orb_->create_policy (BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE,
208 pol);
211 ACE_CString child_poa_name = "childPOA";
212 PortableServer::POA_var child_poa =
213 root_poa->create_POA (child_poa_name.c_str (),
214 poa_manager.in (),
215 policies);
217 // Creation of persistentPOA is over. Destroy the Policy objects.
218 for (CORBA::ULong i = 0;
219 i < policies.length ();
220 ++i)
222 policies[i]->destroy ();
225 if (CORBA::is_nil (child_poa.in ()))
226 ORBSVCS_ERROR_RETURN ((LM_ERROR,
227 " (%P|%t) Unable to initialize the child POA.\n"),
230 PortableServer::ObjectId_var ec_object_id =
231 PortableServer::string_to_ObjectId(object_id_.c_str());
233 child_poa->activate_object_with_id(ec_object_id.in(), this);
235 CORBA::Object_var ec_obj =
236 child_poa->id_to_reference(ec_object_id.in());
238 ec =
239 RtecEventChannelAdmin::EventChannel::_narrow(ec_obj.in());
242 CORBA::String_var str =
243 this->orb_->object_to_string (ec.in ());
245 if (ACE_OS::strcmp(this->ior_file_name_.c_str(), ACE_TEXT("")) != 0)
247 FILE *output_file=
248 ACE_OS::fopen (this->ior_file_name_.c_str(),
249 ACE_TEXT("w"));
250 if (output_file == 0)
251 ORBSVCS_ERROR_RETURN ((LM_ERROR,
252 "Cannot open output file for writing IOR: %s",
253 this->ior_file_name_.c_str()),
255 ACE_OS::fprintf (output_file, "%s", str.in ());
256 ACE_OS::fclose (output_file);
259 if (ACE_OS::strcmp(this->pid_file_name_.c_str(), ACE_TEXT("")) != 0)
261 FILE *pidf =
262 ACE_OS::fopen (this->pid_file_name_.c_str(),
263 ACE_TEXT("w"));
264 if (pidf != 0)
266 ACE_OS::fprintf (pidf,
267 "%ld\n",
268 static_cast<long> (ACE_OS::getpid ()));
269 ACE_OS::fclose (pidf);
273 ORBSVCS_DEBUG ((LM_DEBUG,
274 ACE_TEXT("The EC IOR is <%C>\n"),
275 str.in ()));
277 if (bind_to_naming_service_ && !CORBA::is_nil (naming_context.in ()))
279 CosNaming::Name channel_name (1);
280 channel_name.length (1);
281 channel_name[0].id = CORBA::string_dup (this->service_name_.c_str());
282 naming_context->rebind (channel_name, ec.in ());
285 ORBSVCS_DEBUG ((LM_DEBUG,
286 ACE_TEXT("%C; running event service\n"),
287 __FILE__));
289 this->orb_->run ();
291 if (bind_to_naming_service_ && !CORBA::is_nil (naming_context.in ()))
293 CosNaming::Name channel_name (1);
294 channel_name.length (1);
295 channel_name[0].id = CORBA::string_dup (this->service_name_.c_str());
296 naming_context->unbind (channel_name);
299 if (!CORBA::is_nil (scheduler.in ()) &&
300 !CORBA::is_nil (naming_context.in ()))
302 naming_context->unbind (schedule_name);
306 catch (const CORBA::Exception& ex)
308 ex._tao_print_exception ("EC");
312 return 0;
316 Event_Service::parse_args (int argc, ACE_TCHAR* argv [])
318 // default values...
319 this->service_name_ = "EventService";
321 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("an:o:p:s:q:bx"));
322 int opt;
324 while ((opt = get_opt ()) != EOF)
326 switch (opt)
328 case 'a':
329 // This is processed in main()
330 break;
331 case 'n':
332 this->service_name_ = ACE_TEXT_ALWAYS_CHAR(get_opt.opt_arg ());
333 break;
335 case 'o':
336 this->ior_file_name_ = get_opt.opt_arg ();
337 break;
339 case 'p':
340 this->pid_file_name_ = get_opt.opt_arg ();
341 break;
343 case 'q':
344 this->object_id_ = ACE_TEXT_ALWAYS_CHAR(get_opt.opt_arg ());
345 break;
347 case 'b':
348 this->use_bidir_giop_ = true;
349 break;
351 case 'x':
352 this->bind_to_naming_service_ = false;
353 break;
355 case 's':
356 // It could be just a flag (i.e. no "global" or "local"
357 // argument, but this is consistent with the EC_Multiple
358 // test and also allows for a runtime scheduling service.
360 if (ACE_OS::strcasecmp (get_opt.opt_arg (), ACE_TEXT("global")) == 0)
362 this->scheduler_type_ = ES_SCHED_GLOBAL;
364 else if (ACE_OS::strcasecmp (get_opt.opt_arg (), ACE_TEXT("local")) == 0)
366 this->scheduler_type_ = ES_SCHED_LOCAL;
368 else if (ACE_OS::strcasecmp (get_opt.opt_arg (), ACE_TEXT("none")) == 0)
370 this->scheduler_type_ = ES_SCHED_NONE;
372 else
374 ORBSVCS_DEBUG ((LM_DEBUG,
375 ACE_TEXT("Unknown scheduling type <%s> ")
376 ACE_TEXT("defaulting to none\n"),
377 get_opt.opt_arg ()));
378 this->scheduler_type_ = ES_SCHED_NONE;
380 break;
382 case '?':
383 default:
384 ORBSVCS_DEBUG ((LM_DEBUG,
385 ACE_TEXT("Usage: %s ")
386 ACE_TEXT("-a ")
387 ACE_TEXT("-n service_name ")
388 ACE_TEXT("-o ior_file_name ")
389 ACE_TEXT("-p pid_file_name ")
390 ACE_TEXT("-s <global|local|none> ")
391 ACE_TEXT("-q ec_object_id ")
392 ACE_TEXT("-x [disable naming service bind] ")
393 ACE_TEXT("-b [use bidir giop] ")
394 ACE_TEXT("\n"),
395 argv[0]));
396 return -1;
400 return 0;
404 RtecEventChannelAdmin::ConsumerAdmin_ptr
405 Event_Service::for_consumers (void)
407 return this->ec_impl_->for_consumers ();
410 RtecEventChannelAdmin::SupplierAdmin_ptr
411 Event_Service::for_suppliers (void)
413 return this->ec_impl_->for_suppliers ();
416 void
417 Event_Service::destroy (void)
419 this->ec_impl_->destroy ();
420 this->orb_->shutdown ();
423 RtecEventChannelAdmin::Observer_Handle
424 Event_Service::append_observer (RtecEventChannelAdmin::Observer_ptr observer)
426 return this->ec_impl_->append_observer (observer);
429 void
430 Event_Service::remove_observer (RtecEventChannelAdmin::Observer_Handle handle)
432 this->ec_impl_->remove_observer (handle);