CEC_Event_Loader.cpp

Go to the documentation of this file.
00001 // $Id: CEC_Event_Loader.cpp 77001 2007-02-12 07:54:49Z johnnyw $
00002 
00003 //==========================================================================
00004 // LIBRARY
00005 //   libTAO_CosEvent.so
00006 //
00007 // DESCRIPTION
00008 //   This class allows for dynamically loading
00009 //   the Event Service.
00010 //
00011 // AUTHOR
00012 //   Priyanka Gontla <pgontla@ece.uci.edu>
00013 //   Carlos O'Ryan <coryan@uci.edu>
00014 //   Jon Astle <jon@astle45.fsnet.co.uk>
00015 //
00016 //===========================================================================
00017 
00018 #include "orbsvcs/CosEvent/CEC_Event_Loader.h"
00019 #include "ace/Dynamic_Service.h"
00020 
00021 #include "orbsvcs/CosNamingC.h"
00022 #include "orbsvcs/CosEvent/CEC_EventChannel.h"
00023 #include "orbsvcs/CosEvent/CEC_Default_Factory.h"
00024 
00025 #include "ace/Get_Opt.h"
00026 #include "ace/Argv_Type_Converter.h"
00027 #include "ace/OS_NS_stdio.h"
00028 #include "ace/OS_NS_unistd.h"
00029 #include "tao/debug.h"
00030 
00031 ACE_RCSID (CosEvent,
00032            CEC_Event_Loader,
00033            "$Id: CEC_Event_Loader.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
00034 
00035 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00036 
00037 TAO_CEC_Event_Loader::TAO_CEC_Event_Loader (void) :
00038   attributes_ (0)
00039   , factory_ (0)
00040   , ec_impl_ (0)
00041 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00042   , typed_attributes_ (0)
00043   , typed_ec_impl_ (0)
00044 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00045 {
00046   // Constructor
00047 }
00048 
00049 TAO_CEC_Event_Loader::~TAO_CEC_Event_Loader (void)
00050 {
00051   // Destructor
00052 }
00053 
00054 int
00055 TAO_CEC_Event_Loader::init (int argc, ACE_TCHAR *argv[])
00056 {
00057   try
00058     {
00059       // Copy command line parameter.
00060       ACE_Argv_Type_Converter command_line(argc, argv);
00061 
00062       // ORB initialization boiler plate...
00063       this->orb_=
00064         CORBA::ORB_init (command_line.get_argc(), command_line.get_ASCII_argv(), 0);
00065 
00066       CORBA::Object_var obj =
00067         this->create_object (this->orb_.in (), command_line.get_argc(), command_line.get_TCHAR_argv());
00068 
00069       if (CORBA::is_nil (obj.in() ))
00070         return -1;
00071     }
00072   catch (const CORBA::Exception& ex)
00073     {
00074       ex._tao_print_exception (argv[0]);
00075       return -1;
00076     }
00077   return 0;
00078 }
00079 
00080 
00081 CORBA::Object_ptr
00082 TAO_CEC_Event_Loader::create_object (CORBA::ORB_ptr orb,
00083                                      int argc,
00084                                      ACE_TCHAR *argv[])
00085 {
00086   try
00087     {
00088       // ****************************************************************
00089 
00090       // @@ Some ideas for improvement (not that you have to implement
00091       // them):
00092       //  - Receive a child POA name from the command line, and create
00093       //    all the objects in that child POA (easier to destroy stuff
00094       //    that way).
00095       //  - Receive an option to register the Event Service with the
00096       //    _tao_add_to_IOR_table() stuff..
00097 
00098       // Parse the options, check if we should bind with the naming
00099       // service and under what name...
00100       ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("n:o:p:xrtdb"));
00101       int opt;
00102       const ACE_TCHAR *service_name = ACE_TEXT("CosEventService");
00103       const ACE_TCHAR *ior_file = 0;
00104       const ACE_TCHAR *pid_file = 0;
00105       this->bind_to_naming_service_ = 1;
00106       int use_rebind = 0;
00107       int disconnect_callbacks = 0;
00108 
00109 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00110       // Flag to create a typed event channel
00111       int typed_ec = 0;
00112       // Flag to destroy the event channel on shutdown
00113       int destroy = 0;
00114 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00115 
00116       while ((opt = get_opt ()) != EOF)
00117         {
00118           switch (opt)
00119             {
00120             case 'n':
00121               service_name = get_opt.opt_arg ();
00122               break;
00123 
00124             case 'o':
00125               ior_file = get_opt.opt_arg ();
00126               break;
00127 
00128             case 'p':
00129               pid_file = get_opt.opt_arg ();
00130               break;
00131 
00132             case 'x':
00133               this->bind_to_naming_service_ = 0;
00134               break;
00135 
00136             case 'r':
00137               use_rebind = 1;
00138               break;
00139 
00140             case 'b':
00141               disconnect_callbacks = 1;
00142               break;
00143 
00144 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00145             case 't':
00146               typed_ec = 1;
00147               break;
00148 
00149             case 'd':
00150               destroy = 1;
00151               break;
00152 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00153 
00154             case '?':
00155             default:
00156 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00157               ACE_DEBUG ((LM_DEBUG,
00158                           ACE_TEXT ("Usage: %s ")
00159                           ACE_TEXT ("-n service_name ")
00160                           ACE_TEXT ("-o ior_file_name ")
00161                           ACE_TEXT ("-p pid_file_name ")
00162                           ACE_TEXT ("-x [disable naming service bind]")
00163                           ACE_TEXT ("-r [rebind, no AlreadyBound failures] ")
00164                           ACE_TEXT ("-b [send callBacks on disconnect] ")
00165                           ACE_TEXT ("-t [enable typed event channel]")
00166                           ACE_TEXT ("-d [destroy typed event channelon shutdown] ")
00167                           ACE_TEXT ("\n"),
00168                           argv[0]));
00169 #else
00170               ACE_DEBUG ((LM_DEBUG,
00171                           ACE_TEXT ("Usage: %s ")
00172                           ACE_TEXT ("-n service_name ")
00173                           ACE_TEXT ("-o ior_file_name ")
00174                           ACE_TEXT ("-p pid_file_name ")
00175                           ACE_TEXT ("-x [disable naming service bind] ")
00176                           ACE_TEXT ("-r [rebind, no AlreadyBound failures] ")
00177                           ACE_TEXT ("-b [send callBacks on disconnect] ")
00178                           ACE_TEXT ("\n"),
00179                           argv[0]));
00180 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00181               return CORBA::Object::_nil ();
00182             }
00183         }
00184 
00185       // ***************************************************************
00186 
00187       // POA initialization and activation ...
00188       CORBA::Object_var object =
00189         orb->resolve_initial_references ("RootPOA");
00190       PortableServer::POA_var poa =
00191         PortableServer::POA::_narrow (object.in ());
00192       PortableServer::POAManager_var poa_manager =
00193         poa->the_POAManager ();
00194       poa_manager->activate ();
00195 
00196 
00197       // ****************************************************************
00198 
00199       // Control the event loop
00200       this->terminate_flag_ = 0;
00201 
00202 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00203       if (!typed_ec)
00204         {
00205 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00206 
00207       // Create and activate the event service
00208       this->attributes_ = new TAO_CEC_EventChannel_Attributes(poa.in (),
00209                                                               poa.in ());
00210 
00211       this->attributes_->disconnect_callbacks = disconnect_callbacks;
00212 
00213       this->factory_ = 0;
00214 
00215       this->ec_impl_ = new TAO_CEC_EventChannel (*this->attributes_,
00216                                                  this->factory_,
00217                                                  this->terminate_flag_);
00218 
00219       this->ec_impl_->activate ();
00220 
00221       CosEventChannelAdmin::EventChannel_var event_channel =
00222         this->ec_impl_->_this ();
00223 
00224       if (ior_file != 0)
00225         {
00226           CORBA::String_var ior =
00227             orb->object_to_string (event_channel.in ());
00228 
00229           FILE *iorf = ACE_OS::fopen (ior_file, ACE_TEXT("w"));
00230           if (iorf != 0)
00231             {
00232               ACE_OS::fprintf (iorf, "%s\n", ior.in ());
00233               ACE_OS::fclose (iorf);
00234             }
00235         }
00236 
00237       if (pid_file != 0)
00238         {
00239           FILE *pidf = ACE_OS::fopen (pid_file, ACE_TEXT("w"));
00240           if (pidf != 0)
00241             {
00242               ACE_OS::fprintf (pidf,
00243                                "%ld\n",
00244                                static_cast<long> (ACE_OS::getpid ()));
00245               ACE_OS::fclose (pidf);
00246             }
00247         }
00248 
00249       // ****************************************************************
00250 
00251       this->channel_name_.length (1);
00252 
00253       if (this->bind_to_naming_service_)
00254         {
00255           CORBA::Object_var obj =
00256             orb->resolve_initial_references ("NameService");
00257 
00258           this->naming_context_ =
00259             CosNaming::NamingContext::_narrow (obj.in ());
00260 
00261           this->channel_name_.length (1);
00262           this->channel_name_[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(service_name));
00263 
00264           if (use_rebind)
00265             {
00266               this->naming_context_->rebind (this->channel_name_,
00267                                       event_channel.in ());
00268             }
00269           else
00270             {
00271               this->naming_context_->bind (this->channel_name_,
00272                                     event_channel.in ());
00273             }
00274         }
00275           return CosEventChannelAdmin::EventChannel::_duplicate (event_channel.in () );
00276 
00277 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00278         }
00279       else
00280         {
00281           // If Typed EC, initialize the IFR, then create and activate the typed event service
00282 
00283           // ****************************************************************
00284           // IFR initialization
00285           if (TAO_debug_level >= 10)
00286             {
00287               ACE_DEBUG ((LM_DEBUG,
00288                           ACE_TEXT ("***** Initializing the IFR connection... *****\n")));
00289             }
00290 
00291           CORBA::Repository_var interface_repository;
00292 
00293           CORBA::Object_var ifr_obj_var =
00294             orb->resolve_initial_references ("InterfaceRepository");
00295 
00296           if (CORBA::is_nil(ifr_obj_var.in () ))
00297             {
00298               if (TAO_debug_level >= 10)
00299                 {
00300                   ACE_DEBUG ((LM_DEBUG,
00301                               ACE_TEXT ("***** resolve_initial_references for IFR failed\n *****")));
00302                 }
00303               return CORBA::Object::_nil ();
00304             }
00305           else
00306             {
00307               interface_repository = CORBA::Repository::_narrow(ifr_obj_var.in ());
00308 
00309               if (CORBA::is_nil(interface_repository.in () ))
00310                 {
00311                   if (TAO_debug_level >= 10)
00312                     {
00313                       ACE_DEBUG ((LM_DEBUG,
00314                                   ACE_TEXT ("***** CORBA::Repository::_narrow failed *****\n")));
00315                     }
00316                   return CORBA::Object::_nil ();
00317                 }
00318               else
00319                 {
00320                   if (TAO_debug_level >= 10)
00321                     {
00322                       ACE_DEBUG ((LM_DEBUG,
00323                                   ACE_TEXT ("***** ...IFR connection completed *****\n")));
00324                     }
00325                 }
00326             }
00327 
00328           // Create and activate the typed event service
00329           this->typed_attributes_ = new TAO_CEC_TypedEventChannel_Attributes(poa.in (),
00330                                                                              poa.in (),
00331                                                                              orb,
00332                                                                              interface_repository.in ());
00333           if (destroy == 1)
00334             {
00335               this->typed_attributes_->destroy_on_shutdown = 1;
00336             }
00337 
00338           this->typed_attributes_->disconnect_callbacks = disconnect_callbacks;
00339 
00340           this->factory_ = 0;
00341 
00342           this->typed_ec_impl_ = new TAO_CEC_TypedEventChannel (*this->typed_attributes_,
00343                                                                 this->factory_,
00344                                                                 this->terminate_flag_);
00345 
00346           this->typed_ec_impl_->activate ();
00347 
00348           CosTypedEventChannelAdmin::TypedEventChannel_var event_channel =
00349             this->typed_ec_impl_->_this ();
00350 
00351           if (ior_file != 0)
00352             {
00353               CORBA::String_var ior =
00354                 orb->object_to_string (event_channel.in ());
00355 
00356               FILE *iorf = ACE_OS::fopen (ior_file, ACE_TEXT("w"));
00357               if (iorf != 0)
00358                 {
00359                   ACE_OS::fprintf (iorf, "%s\n", ior.in ());
00360                   ACE_OS::fclose (iorf);
00361                 }
00362             }
00363 
00364           if (pid_file != 0)
00365             {
00366               FILE *pidf = ACE_OS::fopen (pid_file, ACE_TEXT("w"));
00367               if (pidf != 0)
00368                 {
00369                   ACE_OS::fprintf (pidf,
00370                                    "%ld\n",
00371                                    static_cast<long> (ACE_OS::getpid ()));
00372                   ACE_OS::fclose (pidf);
00373                 }
00374             }
00375 
00376           // ****************************************************************
00377 
00378           this->channel_name_.length (1);
00379 
00380           if (this->bind_to_naming_service_)
00381             {
00382               CORBA::Object_var obj =
00383                 orb->resolve_initial_references ("NameService");
00384 
00385               this->naming_context_ =
00386                 CosNaming::NamingContext::_narrow (obj.in ());
00387 
00388               this->channel_name_.length (1);
00389               this->channel_name_[0].id = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR(service_name));
00390 
00391               if (use_rebind)
00392                 {
00393                   this->naming_context_->rebind (this->channel_name_,
00394                                                  event_channel.in ());
00395                 }
00396               else
00397                 {
00398                   this->naming_context_->bind (this->channel_name_,
00399                                                event_channel.in ());
00400                 }
00401             }
00402           return CosTypedEventChannelAdmin::TypedEventChannel::_duplicate (event_channel.in () );
00403         }
00404 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00405 
00406       // ****************************************************************
00407     }
00408   catch (const CORBA::Exception& ex)
00409     {
00410       ex._tao_print_exception (argv[0]);
00411       return CORBA::Object::_nil ();
00412     }
00413 }
00414 
00415 int
00416 TAO_CEC_Event_Loader::fini (void)
00417 {
00418   //   + Since it was activated with _this() you have to do the
00419   //   canonical:
00420   //     get_object_id
00421   try
00422     {
00423 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00424       if(this->typed_ec_impl_)
00425         {
00426           // Release the resources of the Typed Event Channel
00427           this->typed_ec_impl_->destroy ();
00428 
00429           // Deactivate the Typed EC
00430           // This will raise an exception if destroy == 1
00431           PortableServer::POA_var t_poa =
00432           this->typed_ec_impl_->_default_POA ();
00433 
00434           PortableServer::ObjectId_var t_id =
00435           t_poa->servant_to_id (this->typed_ec_impl_);
00436 
00437           t_poa->deactivate_object (t_id.in ());
00438         }
00439 #else
00440       // Release the resources of the Event Channel
00441       this->ec_impl_->destroy ();
00442 
00443       // Deactivate the EC
00444       PortableServer::POA_var poa =
00445         this->ec_impl_->_default_POA ();
00446 
00447       PortableServer::ObjectId_var id =
00448         poa->servant_to_id (this->ec_impl_);
00449 
00450       poa->deactivate_object (id.in ());
00451 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00452     }
00453   catch (const CORBA::Exception&)
00454     {
00455       // Do Nothing
00456     }
00457 
00458   try
00459     {
00460       // Unbind the Naming Service
00461       if (this->bind_to_naming_service_)
00462         {
00463           this->naming_context_->unbind (this->channel_name_);
00464         }
00465 
00466 #if defined (TAO_HAS_TYPED_EVENT_CHANNEL)
00467       // Since we created them, we also have to delete them.
00468       delete this->typed_attributes_;
00469       delete this->typed_ec_impl_;
00470 #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */
00471       delete this->attributes_;
00472       delete this->ec_impl_;
00473     }
00474   catch (const CORBA::Exception&)
00475     {
00476       // Do Nothing
00477       return -1;
00478     }
00479 
00480   return 0;
00481 }
00482 
00483 TAO_END_VERSIONED_NAMESPACE_DECL
00484 
00485 ACE_FACTORY_DEFINE (TAO_Event_Serv, TAO_CEC_Event_Loader)

Generated on Tue Feb 2 17:44:51 2010 for TAO_CosEvent by  doxygen 1.4.7