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;
34 if (use_thread_per_consumer
)
35 TAO_EC_TPC_Factory::init_svcs ();
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)
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_
;
58 delete this->sched_impl_
;
59 this->sched_impl_
= 0;
63 Event_Service::run (int argc
, ACE_TCHAR
* argv
[])
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
);
73 CORBA::ORB_init (argc
, argv
);
75 if (this->parse_args (argc
, argv
) == -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"),
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
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
)
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"),
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 (),
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
185 CORBA::ULong index
= 0;
188 CORBA::PolicyList
policies (3);
192 policies
.length (index
++);
194 root_poa
->create_id_assignment_policy (PortableServer::USER_ID
);
196 policies
.length (index
++);
198 root_poa
->create_lifespan_policy (PortableServer::PERSISTENT
);
201 if (this->use_bidir_giop_
== true)
204 pol
<<= BiDirPolicy::BOTH
;
205 policies
.length (index
++);
207 this->orb_
->create_policy (BiDirPolicy::BIDIRECTIONAL_POLICY_TYPE
,
211 ACE_CString child_poa_name
= "childPOA";
212 PortableServer::POA_var child_poa
=
213 root_poa
->create_POA (child_poa_name
.c_str (),
217 // Creation of persistentPOA is over. Destroy the Policy objects.
218 for (CORBA::ULong i
= 0;
219 i
< policies
.length ();
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());
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)
248 ACE_OS::fopen (this->ior_file_name_
.c_str(),
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)
262 ACE_OS::fopen (this->pid_file_name_
.c_str(),
266 ACE_OS::fprintf (pidf
,
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"),
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"),
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");
316 Event_Service::parse_args (int argc
, ACE_TCHAR
* argv
[])
319 this->service_name_
= "EventService";
321 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("an:o:p:s:q:bx"));
324 while ((opt
= get_opt ()) != EOF
)
329 // This is processed in main()
332 this->service_name_
= ACE_TEXT_ALWAYS_CHAR(get_opt
.opt_arg ());
336 this->ior_file_name_
= get_opt
.opt_arg ();
340 this->pid_file_name_
= get_opt
.opt_arg ();
344 this->object_id_
= ACE_TEXT_ALWAYS_CHAR(get_opt
.opt_arg ());
348 this->use_bidir_giop_
= true;
352 this->bind_to_naming_service_
= false;
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
;
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
;
384 ORBSVCS_DEBUG ((LM_DEBUG
,
385 ACE_TEXT("Usage: %s ")
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] ")
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 ();
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
);
430 Event_Service::remove_observer (RtecEventChannelAdmin::Observer_Handle handle
)
432 this->ec_impl_
->remove_observer (handle
);