Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

ORB_Core.cpp

Go to the documentation of this file.
00001 #include "tao_pch.h"
00002 // $Id: ORB_Core.cpp,v 1.1.1.4.2.5 2003/04/21 19:10:24 chad Exp $
00003 
00004 #include "ORB_Core.h"
00005 #include "ORB_Table.h"
00006 
00007 
00008 #include "TAO_Internal.h"
00009 #include "default_client.h"
00010 #include "default_server.h"
00011 #include "default_resource.h"
00012 #include "debug.h"
00013 #include "MProfile.h"
00014 #include "Profile.h"
00015 #include "Stub.h"
00016 #include "Leader_Follower.h"
00017 #include "Connector_Registry.h"
00018 
00019 #include "Sync_Strategies.h"
00020 
00021 #include "Object_Loader.h"
00022 
00023 #include "ObjectIDList.h"
00024 
00025 #include "Services_Activate.h"
00026 #include "Invocation.h"
00027 #include "BiDir_Adapter.h"
00028 
00029 
00030 #include "Collocation_Resolver.h"
00031 #include "Endpoint_Selector_Factory.h"
00032 #include "Flushing_Strategy.h"
00033 #include "Request_Dispatcher.h"
00034 #include "Stub_Factory.h"
00035 #include "Thread_Lane_Resources.h"
00036 #include "Thread_Lane_Resources_Manager.h"
00037 
00038 #include "Protocols_Hooks.h"
00039 
00040 
00041 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
00042 # include "Buffering_Constraint_Policy.h"
00043 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
00044 
00045 #include "tao/LF_Event_Loop_Thread_Helper.h"
00046 
00047 #if (TAO_HAS_INTERCEPTORS == 1)
00048 #include "tao/ClientRequestInfo.h"
00049 #endif  /* TAO_HAS_INTERCEPTORS == 1  */
00050 
00051 #include "ace/Object_Manager.h"
00052 #include "ace/Dynamic_Service.h"
00053 #include "ace/Arg_Shifter.h"
00054 #include "ace/Argv_Type_Converter.h"
00055 
00056 #include "Codeset_Manager.h"
00057 
00058 #if !defined (__ACE_INLINE__)
00059 # include "ORB_Core.i"
00060 #endif /* ! __ACE_INLINE__ */
00061 
00062 ACE_RCSID (tao,
00063            ORB_Core,
00064            "$Id: ORB_Core.cpp,v 1.1.1.4.2.5 2003/04/21 19:10:24 chad Exp $")
00065 
00066 // ****************************************************************
00067 
00068 CORBA::Environment&
00069 TAO_default_environment ()
00070 {
00071   return *TAO_TSS_RESOURCES::instance ()->default_environment_;
00072 }
00073 
00074 // ****************************************************************
00075 
00076 // Initialize instance_ to 0, since this is what we test for in the call
00077 // to instance ().  Note that this does not require a constructor call, so
00078 // it is always initialized by the time that instance () can be called.
00079 TAO_ORB_Core_Static_Resources* TAO_ORB_Core_Static_Resources::instance_ = 0;
00080 
00081 // Force an instance to be created at module initialization time,
00082 // since we do not want to worry about double checked locking and
00083 // the race condition to initialize the lock.
00084 TAO_ORB_Core_Static_Resources* TAO_ORB_Core_Static_Resources::initialization_reference_ =
00085   TAO_ORB_Core_Static_Resources::instance ();
00086 
00087 TAO_ORB_Core_Static_Resources*
00088 TAO_ORB_Core_Static_Resources::instance (void)
00089 {
00090   if (TAO_ORB_Core_Static_Resources::instance_ == 0)
00091     {
00092       // This new is never freed on purpose.  The data specified by
00093       // it needs to be around for the last shared library that references
00094       // this class.  This could occur in a destructor in a shared library
00095       // that is unloaded after this one.  One solution to avoid this
00096       // harmless memory leak would be to use reference counting.
00097       ACE_NEW_RETURN (TAO_ORB_Core_Static_Resources::instance_,
00098                       TAO_ORB_Core_Static_Resources (),
00099                       0);
00100     }
00101 
00102   return TAO_ORB_Core_Static_Resources::instance_;
00103 }
00104 
00105 TAO_ORB_Core_Static_Resources::TAO_ORB_Core_Static_Resources (void)
00106   : sync_scope_hook_ (0),
00107     protocols_hooks_name_ ("Protocols_Hooks"),
00108     timeout_hook_ (0),
00109     connection_timeout_hook_ (0),
00110     endpoint_selector_factory_name_ ("Default_Endpoint_Selector_Factory"),
00111     thread_lane_resources_manager_factory_name_ ("Default_Thread_Lane_Resources_Manager_Factory"),
00112     collocation_resolver_name_ ("Default_Collocation_Resolver"),
00113     stub_factory_name_ ("Default_Stub_Factory"),
00114     resource_factory_name_ ("Resource_Factory"),
00115     dynamic_adapter_name_ ("Dynamic_Adapter"),
00116     ifr_client_adapter_name_ ("IFR_Client_Adapter"),
00117     typecodefactory_adapter_name_ ("TypeCodeFactory_Adapter"),
00118     poa_factory_name_ ("TAO_POA"),
00119     poa_factory_directive_ ("dynamic TAO_POA Service_Object * TAO_PortableServer:_make_TAO_Object_Adapter_Factory()")
00120 {
00121 }
00122 
00123 // ****************************************************************
00124 
00125 TAO_ORB_Core::TAO_ORB_Core (const char *orbid)
00126   : protocols_hooks_ (0),
00127     lock_ (),
00128     thread_lane_resources_manager_ (0),
00129     collocation_resolver_ (0),
00130     stub_factory_ (0),
00131     protocol_factories_ (0),
00132     implrepo_service_ (CORBA::Object::_nil ()),
00133     use_implrepo_ (0),
00134     typecode_factory_ (CORBA::Object::_nil ()),
00135     dynany_factory_ (CORBA::Object::_nil ()),
00136     ior_manip_factory_ (CORBA::Object::_nil ()),
00137     ior_table_ (CORBA::Object::_nil ()),
00138     orb_ (),
00139     root_poa_ (),
00140     portable_group_poa_hooks_ (0),
00141     orb_params_ (),
00142     init_ref_map_ (TAO_DEFAULT_OBJECT_REF_TABLE_SIZE),
00143     object_ref_table_ (),
00144     orbid_ (ACE_OS::strdup (orbid ? orbid : "")),
00145     resource_factory_ (0),
00146 #if 0
00147     /// @@todo:Need to go one day
00148     message_block_dblock_allocator_ (0),
00149     message_block_buffer_allocator_ (0),
00150     message_block_msgblock_allocator_ (0),
00151 #endif /*if 0*/
00152 //    server_id_ (0),
00153     client_factory_ (0),
00154     server_factory_ (0),
00155     opt_for_collocation_ (1),
00156     use_global_collocation_ (1),
00157     collocation_strategy_ (THRU_POA),
00158 
00159 #if (TAO_HAS_CORBA_MESSAGING == 1)
00160 
00161     policy_manager_ (0),
00162     default_policies_ (0),
00163     policy_current_ (0),
00164 
00165 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
00166 
00167     poa_current_ (),
00168     adapter_registry_ (this),
00169     poa_adapter_ (0),
00170     tm_ (),
00171     tss_cleanup_funcs_ (),
00172     tss_resources_ (),
00173     orb_resources_ (),
00174     has_shutdown_ (1),  // Start the ORB in a  "shutdown" state.  Only
00175                         // after CORBA::ORB_init() is called will the
00176                         // ORB no longer be shutdown.  This does not
00177                         // mean that the ORB can be reinitialized.  It
00178                         // can only be initialized once.
00179     thread_per_connection_use_timeout_ (1),
00180     endpoint_selector_factory_ (0),
00181 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
00182     eager_buffering_sync_strategy_ (0),
00183     delayed_buffering_sync_strategy_ (0),
00184 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
00185     transport_sync_strategy_ (0),
00186     refcount_ (1),
00187     policy_factory_registry_ (),
00188 #if (TAO_HAS_INTERCEPTORS == 1)
00189     pi_current_ (0),
00190     client_request_interceptors_ (),
00191     server_request_interceptors_ (),
00192 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
00193     ior_interceptors_ (),
00194     parser_registry_ (),
00195     bidir_adapter_ (0),
00196     bidir_giop_policy_ (0),
00197     flushing_strategy_ (0),
00198     codeset_manager_ (0)
00199 {
00200 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
00201 
00202   ACE_NEW (this->eager_buffering_sync_strategy_,
00203            TAO_Eager_Buffering_Sync_Strategy);
00204 
00205   ACE_NEW (this->delayed_buffering_sync_strategy_,
00206            TAO_Delayed_Buffering_Sync_Strategy);
00207 
00208 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
00209 
00210 #if (TAO_HAS_CORBA_MESSAGING == 1)
00211 
00212   ACE_NEW (this->policy_manager_,
00213            TAO_Policy_Manager);
00214 
00215   ACE_NEW (this->default_policies_,
00216            TAO_Policy_Set (TAO_POLICY_ORB_SCOPE));
00217 
00218   ACE_NEW (this->policy_current_,
00219            TAO_Policy_Current);
00220 
00221 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
00222 
00223   ACE_NEW (this->transport_sync_strategy_,
00224            TAO_Transport_Sync_Strategy);
00225 
00226   // Initialize the default request dispatcher.
00227   ACE_NEW (this->request_dispatcher_,
00228            TAO_Request_Dispatcher);
00229 }
00230 
00231 TAO_ORB_Core::~TAO_ORB_Core (void)
00232 {
00233   delete this->thread_lane_resources_manager_;
00234 
00235   delete this->flushing_strategy_;
00236 
00237   ACE_OS::free (this->orbid_);
00238 
00239 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
00240 
00241   delete this->eager_buffering_sync_strategy_;
00242   delete this->delayed_buffering_sync_strategy_;
00243 
00244 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
00245 
00246 #if (TAO_HAS_CORBA_MESSAGING == 1)
00247 
00248   CORBA::release (this->policy_manager_);
00249   delete this->default_policies_;
00250   CORBA::release (this->policy_current_);
00251 
00252 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
00253 
00254   delete this->transport_sync_strategy_;
00255 
00256   delete this->request_dispatcher_;
00257 }
00258 
00259 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
00260 
00261 CORBA::Policy_ptr
00262 TAO_ORB_Core::default_buffering_constraint (void) const
00263 {
00264   return this->default_policies_->
00265               get_cached_policy (TAO_CACHED_POLICY_BUFFERING_CONSTRAINT);
00266 }
00267 
00268 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
00269 
00270 
00271 int
00272 TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL)
00273 {
00274   // Right now, this code expects to begin parsing in argv[1] rather
00275   // than argv[0].  I don't think that's wise.  I think we need to
00276   // change that convention to argv[0] and let the initializing code
00277   // make any necessary shifts.
00278   //
00279   // Parse arguments to the ORB.  Typically the ORB is passed
00280   // arguments straight from the command line, so we will simply pass
00281   // through them and respond to the ones we understand and ignore
00282   // those we don't.
00283   //
00284   // In some instances, we may actually build another vector of
00285   // arguments and stash it for use initializing other components such
00286   // as the RootPOA.
00287 
00288   // @@ GIOPLite should be an alternative ORB Messaging protocols, fredk
00289   // int giop_lite = 0;
00290 
00291   CORBA::Boolean use_ior = 1;
00292   int cdr_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF;
00293 
00294   // The following things should be changed to use the ACE_Env_Value<>
00295   // template sometime.
00296 
00297   // Name Service port use for Multicast
00298   u_short ns_port = 0;
00299 
00300   // Trading Service port used for Multicast
00301   u_short ts_port = 0;
00302 
00303   // Implementation Repository Service port #.
00304   u_short ir_port = 0;
00305 
00306   // Buffer sizes for kernel socket buffers
00307   // @@ should be a default defined for each protocol implementation?
00308   //    since we may have protocols loaded which use shared memory of
00309   //    some form, fredk
00310   long rcv_sock_size = -1;
00311   long snd_sock_size = -1;
00312 
00313   // Use TCP_NODELAY.
00314   int nodelay = 1;
00315 
00316   // Use dotted decimal addresses
00317   // @@ This option will be treated as a suggestion to each loaded
00318   //    protocol to use a character representation for the numeric
00319   //    address, otherwise use a logical name. fredk
00320 #if (TAO_USE_DOTTED_DECIMAL_ADDRESSES == 1)
00321   int dotted_decimal_addresses = 1;
00322 #else
00323   int dotted_decimal_addresses = 0;
00324 #endif /* TAO_USE_DOTTED_DECIMAL_ADDRESSES */
00325 
00326 #if defined (TAO_STD_PROFILE_COMPONENTS)
00327   int std_profile_components = 1;
00328 #else
00329   int std_profile_components = 0;
00330 #endif /* TAO_STD_PROFILE_COMPONENTS */
00331 
00332   // Copy command line parameter not to use original.
00333   ACE_Argv_Type_Converter command_line(argc, argv);
00334 
00335   ACE_Arg_Shifter arg_shifter (command_line.get_argc(),
00336                                command_line.get_TCHAR_argv());
00337 
00338   while (arg_shifter.is_anything_left ())
00339     {
00340       const ACE_TCHAR *current_arg = 0;
00341 
00342       ////////////////////////////////////////////////////////////////
00343       // begin with the 'parameterless' flags                       //
00344       ////////////////////////////////////////////////////////////////
00345       if ((current_arg = arg_shifter.get_the_parameter
00346                 (ACE_LIB_TEXT("-ORBDottedDecimalAddresses"))))
00347         {
00348           // Use dotted decimal addresses
00349           // @@ this should be renamed.  See above comment. fredk
00350           dotted_decimal_addresses =
00351             ACE_OS::atoi (current_arg);
00352 
00353           arg_shifter.consume_arg ();
00354         }
00355       else if ((current_arg = arg_shifter.get_the_parameter
00356                 (ACE_LIB_TEXT("-ORBEndpoint"))))
00357         {
00358           // Each "endpoint" is of the form:
00359           //
00360           //   protocol://V.v@addr1,addr2,...,addrN
00361           //
00362           // or:
00363           //
00364           //   protocol://addr1,addr2,...,addrN
00365           //
00366           // where "V.v" is an optional protocol version for each
00367           // addr.  All endpoint strings should be of the above
00368           // form(s).
00369           //
00370           // Multiple sets of endpoint may be seperated by a semi-colon `;'.
00371           // For example:
00372           //
00373           //   corbaloc:space:2001,1.2@odyssey:2010;uiop://foo,bar
00374           //
00375           // All endpoint strings should be of the above form(s).
00376 
00377           this->set_endpoint_helper (ACE_TEXT_ALWAYS_CHAR(current_arg)
00378                                      ACE_ENV_ARG_PARAMETER);
00379           ACE_CHECK_RETURN (-1);
00380 
00381           arg_shifter.consume_arg ();
00382         }
00383       else if ((current_arg = arg_shifter.get_the_parameter
00384                 (ACE_LIB_TEXT("-ORBNameServicePort"))))
00385         {
00386           // Specify the port number for the NameService.
00387           // Unrelated to ORB Protocols, this is used for multicast.
00388 
00389           ns_port = (CORBA::UShort) ACE_OS::atoi (current_arg);
00390 
00391           arg_shifter.consume_arg ();
00392         }
00393       else if ((current_arg = arg_shifter.get_the_parameter
00394                 (ACE_LIB_TEXT("-ORBMulticastDiscoveryEndpoint"))))
00395         {
00396           // Specify mcast address:port@network_interface for the
00397           // Naming Service Multicast Discovery Protocol.
00398           // If there is no colon, its only the port no.
00399           // If there is a '@' also, it means that the network
00400           // interface name is specified.
00401           this->orb_params ()->mcast_discovery_endpoint (ACE_TEXT_ALWAYS_CHAR(current_arg));
00402 
00403           arg_shifter.consume_arg ();
00404         }
00405       else if ((current_arg = arg_shifter.get_the_parameter
00406                 (ACE_LIB_TEXT("-ORBNodelay"))))
00407         {
00408           // Use TCP_NODELAY or not.
00409           nodelay =
00410             ACE_OS::atoi (current_arg);
00411 
00412           arg_shifter.consume_arg ();
00413         }
00414       else if ((current_arg = arg_shifter.get_the_parameter
00415                 (ACE_LIB_TEXT("-ORBTradingServicePort"))))
00416         {
00417           // Specify the port number for the NameService.
00418 
00419           ts_port = (CORBA::UShort) ACE_OS::atoi (current_arg);
00420 
00421           arg_shifter.consume_arg ();
00422         }
00423       else if ((current_arg = arg_shifter.get_the_parameter
00424                 (ACE_LIB_TEXT("-ORBImplRepoServicePort"))))
00425         {
00426           // Specify the multicast port number for the Implementation
00427           // Repository.
00428           ir_port = (CORBA::UShort) ACE_OS::atoi (current_arg);
00429 
00430           arg_shifter.consume_arg ();
00431         }
00432       else if ((current_arg = arg_shifter.get_the_parameter
00433                 (ACE_LIB_TEXT("-ORBRcvSock"))))
00434         {
00435           // @@ All protocol implementation may not use sockets, so
00436           //    this can either be a generic I/O Buffer size or
00437           //    Buffer info can be a per protocol specification, fredk
00438 
00439           // Specify the size of the socket's receive buffer
00440 
00441           rcv_sock_size = ACE_OS::atoi (current_arg);
00442 
00443           arg_shifter.consume_arg ();
00444         }
00445       else if ((current_arg = arg_shifter.get_the_parameter
00446                 (ACE_LIB_TEXT("-ORBSndSock"))))
00447         {
00448           // @@ All protocol implementation may not use sockets, so
00449           //    this can either be a generic I/O Buffer size or
00450           //    Buffer info can be a per protocol specification, fredk
00451 
00452           // Specify the size of the socket's send buffer
00453           snd_sock_size = ACE_OS::atoi (current_arg);
00454 
00455           arg_shifter.consume_arg ();
00456         }
00457       else if ((current_arg = arg_shifter.get_the_parameter
00458                 (ACE_LIB_TEXT("-ORBObjRefStyle"))))
00459         {
00460           // Specifies the style of printed objrefs: URL or IOR
00461           //
00462           // BEGIN COMMENTS FROM IIOP-1.4 On Win32, we should be
00463           // collecting information from the Registry such as what
00464           // ORBs are configured, specific configuration details like
00465           // whether they generate IOR or URL style stringified
00466           // objrefs and which addresses they listen to (e.g. allowing
00467           // multihomed hosts to implement firewalls), user-meaningful
00468           // orb names (they will normally indicate domains), and
00469           // more.
00470           //
00471           // On UNIX, we should collect that from some private config
00472           // file.
00473           //
00474           // Instead, this just treats the "internet" ORB name
00475           // specially and makes it always use URL-style stringified
00476           // objrefs, where the hostname and TCP port number are
00477           // explicit (and the whole objref is readable by mortals).
00478           // BEGIN COMMENTS FROM IIOP-1.4
00479           const ACE_TCHAR *opt = current_arg;
00480           if (ACE_OS::strcasecmp (opt,
00481                                   ACE_LIB_TEXT("URL")) == 0)
00482             use_ior = 0;
00483 
00484           arg_shifter.consume_arg ();
00485         }
00486       else if ((current_arg = arg_shifter.get_the_parameter
00487                 (ACE_LIB_TEXT("-ORBCollocationStrategy"))))
00488         {
00489           // Specify which collocation policy we want to use.
00490           const ACE_TCHAR *opt = current_arg;
00491           if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("thru_poa")) == 0)
00492             this->collocation_strategy_ = THRU_POA;
00493           else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("direct")) == 0)
00494             this->collocation_strategy_ = DIRECT;
00495 
00496           arg_shifter.consume_arg ();
00497         }
00498       else if ((current_arg = arg_shifter.get_the_parameter
00499                 (ACE_LIB_TEXT("-ORBCollocation"))))
00500         {
00501           // Specify whether we want to optimize against collocation
00502           // objects.  Valid arguments are: "yes" and "no".
00503           // Default is yes.
00504 
00505           int yes_implies_global = 0;
00506 
00507           const ACE_TCHAR *opt = current_arg;
00508           if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("YES")) == 0)
00509             {
00510               yes_implies_global = 1;
00511               ACE_DEBUG ((LM_WARNING,
00512                           ACE_LIB_TEXT ("WARNING: using '-ORBCollocation YES' is obsolete ")
00513                           ACE_LIB_TEXT ("and implies '-ORBCollocation global'")
00514                           ACE_LIB_TEXT ("  Please use '-ORBCollocation global' instead.\n")));
00515             }
00516 
00517           if (yes_implies_global ||
00518               ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("global")) == 0)
00519             {
00520               this->opt_for_collocation_ = 1;
00521               this->use_global_collocation_ = 1;
00522             }
00523           else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("NO")) == 0)
00524             this->opt_for_collocation_ = 0;
00525           else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("per-orb")) == 0)
00526             {
00527               this->opt_for_collocation_ = 1;
00528               this->use_global_collocation_ = 0;
00529             }
00530 
00531           arg_shifter.consume_arg ();
00532         }
00533       else if ((current_arg = arg_shifter.get_the_parameter
00534                 (ACE_LIB_TEXT("-ORBGlobalCollocation"))))
00535         // Specify whether we want to use collocation across ORBs;
00536         // i.e. all the ORBs in the same address space use collocated
00537         // calls.
00538         {
00539           ACE_DEBUG ((LM_WARNING,
00540                       ACE_LIB_TEXT ("WARNING: -ORBGlobalCollocation option is obsolete.")
00541                       ACE_LIB_TEXT ("  Please use '-ORBCollocation global/per-orb/no'")
00542                       ACE_LIB_TEXT ("instead.\n")));
00543 
00544           const ACE_TCHAR *opt = current_arg;
00545           if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("YES")) == 0)
00546             this->use_global_collocation_ = 1;
00547           else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("NO")) == 0)
00548             this->use_global_collocation_ = 0;
00549 
00550           arg_shifter.consume_arg ();
00551         }
00552       else if ((current_arg = arg_shifter.get_the_parameter
00553                 (ACE_LIB_TEXT("-ORBPreconnect"))))
00554         {
00555 #if 0
00556           /*
00557            *
00558            *  TODO: Needs to go. Leaving it around for things to
00559            *  settle down.
00560            */
00561           // Get a string which describes the connections we want to
00562           // cache up-front, thus reducing the latency of the first call.
00563           //
00564           // For example,  specify -ORBpreconnect once for each
00565           // protocol:
00566           //
00567           //   -ORBpreconnect iiop://tango:10015,watusi:10016
00568           //   -ORBpreconnect busX_iop://board1:0x07450000,board2,0x08450000
00569           //
00570           // Or chain all possible endpoint designations together:
00571           //
00572           //   -ORBpreconnect iiop://tango:10015,watusi:10016/;
00573           //              busX_iop://board1:0x07450000,board2,0x08450000/
00574           //
00575           // The old style command line only works for IIOP:
00576           //    -ORBpreconnect tango:10015,tango:10015,watusi:10016
00577 
00578           ACE_CString preconnections (ACE_TEXT_ALWAYS_CHAR(current_arg));
00579 
00580 
00581           if (this->orb_params ()->preconnects (preconnections) != 0)
00582             {
00583               ACE_ERROR ((LM_ERROR,
00584                           ACE_LIB_TEXT ("(%P|%t)\n")
00585                           ACE_LIB_TEXT ("Invalid preconnect(s)")
00586                           ACE_LIB_TEXT ("specified:\n%s\n"),
00587                           preconnections.c_str ()));
00588               ACE_THROW_RETURN (CORBA::BAD_PARAM (
00589                                   CORBA::SystemException::_tao_minor_code (
00590                                     TAO_ORB_CORE_INIT_LOCATION_CODE,
00591                                     EINVAL),
00592                                   CORBA::COMPLETED_NO),
00593                                 -1);
00594             }
00595 #endif /*if 0*/
00596 
00597           // validate_connection() supports the same functionality as
00598           // the -ORBPreconnect option, and more.  Multiple
00599           // preconnections are also provided by validate_connection()
00600           // via "banded connections."
00601           ACE_ERROR ((LM_WARNING,
00602                       ACE_LIB_TEXT ("(%P|%t) -ORBPreconnect is ")
00603                       ACE_LIB_TEXT ("deprecated.\n")
00604                       ACE_LIB_TEXT ("(%P|%t) Use validate_connection()")
00605                       ACE_LIB_TEXT ("at run-time, instead.\n")));
00606 
00607           arg_shifter.consume_arg ();
00608         }
00609       else if ((current_arg = arg_shifter.get_the_parameter
00610                 (ACE_LIB_TEXT("-ORBCDRTradeoff"))))
00611         {
00612           cdr_tradeoff = ACE_OS::atoi (current_arg);
00613 
00614           arg_shifter.consume_arg ();
00615         }
00616 
00617       // A new <ObjectID>:<IOR> mapping has been specified. This will be
00618       // used by the resolve_initial_references ().
00619 
00620       else if ((current_arg = arg_shifter.get_the_parameter
00621                 (ACE_LIB_TEXT("-ORBInitRef"))))
00622         {
00623           const ACE_TCHAR *pos = ACE_OS::strchr (current_arg, '=');
00624           if (pos == 0)
00625             {
00626               ACE_ERROR ((LM_ERROR,
00627                           ACE_LIB_TEXT ("Invalid ORBInitRef argument '%s'")
00628                           ACE_LIB_TEXT ("format is ObjectID=IOR\n"),
00629                           current_arg));
00630               ACE_THROW_RETURN (CORBA::INTERNAL (
00631                                   CORBA::SystemException::_tao_minor_code (
00632                                     TAO_ORB_CORE_INIT_LOCATION_CODE,
00633                                     0),
00634                                   CORBA::COMPLETED_NO),
00635                                 -1);
00636             }
00637           ACE_CString object_id (ACE_TEXT_ALWAYS_CHAR(current_arg),
00638                                  pos - current_arg);
00639           ACE_CString IOR (ACE_TEXT_ALWAYS_CHAR(pos + 1));
00640           if (this->init_ref_map_.bind (object_id, IOR) != 0)
00641             {              ACE_ERROR ((LM_ERROR,
00642                           ACE_LIB_TEXT ("Cannot store ORBInitRef ")
00643                           ACE_LIB_TEXT ("argument '%s'\n"),
00644                           current_arg));
00645               ACE_THROW_RETURN (CORBA::INTERNAL (
00646                                   CORBA::SystemException::_tao_minor_code (
00647                                     TAO_ORB_CORE_INIT_LOCATION_CODE,
00648                                     0),
00649                                   CORBA::COMPLETED_NO),
00650                                 -1);
00651             }
00652           arg_shifter.consume_arg ();
00653         }
00654       else if ((current_arg = arg_shifter.get_the_parameter
00655                 (ACE_LIB_TEXT("-ORBDefaultInitRef"))))
00656         {
00657           // Set the list of prefixes from -ORBDefaultInitRef.
00658           this->orb_params ()->default_init_ref (ACE_TEXT_ALWAYS_CHAR(current_arg));
00659 
00660           arg_shifter.consume_arg ();
00661         }
00662       else if ((current_arg = arg_shifter.get_the_parameter
00663                 (ACE_LIB_TEXT("-ORBStdProfileComponents"))))
00664         {
00665           std_profile_components =
00666             ACE_OS::atoi (current_arg);
00667           arg_shifter.consume_arg ();
00668         }
00669       else if ((current_arg = arg_shifter.get_the_parameter
00670                 (ACE_LIB_TEXT("-ORBResources"))))
00671         {
00672           ACE_DEBUG ((LM_WARNING,
00673                       ACE_LIB_TEXT ("\"-ORBResources\" has been ")
00674                       ACE_LIB_TEXT ("deprecated.\n")));
00675 
00676           arg_shifter.consume_arg ();
00677         }
00678       else if ((current_arg = arg_shifter.get_the_parameter
00679                 (ACE_LIB_TEXT("-ORBLogFile"))))
00680         {
00681           // redirect all ACE_DEBUG and ACE_ERROR output to a file
00682           // USAGE: -ORBLogFile <file>
00683           // default: if <file> is present     = append
00684           //          if <file> is not present = create
00685 
00686           const ACE_TCHAR *file_name = current_arg;
00687           arg_shifter.consume_arg ();
00688 
00689           // would rather use ACE_OSTREAM_TYPE out here..
00690           // but need ACE_FSTREAM_TYPE to call ->open(...)
00691           // and haven't found such a macro to rep FILE* and/or fstream*
00692 
00693 #if defined (ACE_LACKS_IOSTREAM_TOTALLY)
00694 
00695           FILE* output_stream = ACE_OS::fopen (file_name, ACE_LIB_TEXT("a"));
00696 
00697           ACE_LOG_MSG->msg_ostream (output_stream, 1);
00698 
00699 #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
00700 
00701           ofstream* output_stream = 0;
00702 
00703           //
00704           // note: we are allocating dynamic memory here....but
00705           // I assume it will persist for the life of the program
00706           //
00707 
00708           ACE_NEW_THROW_EX (output_stream,
00709                             ofstream (),
00710                             CORBA::NO_MEMORY (
00711                               CORBA::SystemException::_tao_minor_code (
00712                                 TAO_ORB_CORE_INIT_LOCATION_CODE,
00713                                 ENOMEM),
00714                               CORBA::COMPLETED_NO));
00715           ACE_CHECK_RETURN (-1);
00716 
00717           output_stream->open (file_name, ios::out | ios::app);
00718 
00719           if (!output_stream->bad ())
00720             {
00721               ACE_LOG_MSG->msg_ostream (output_stream, 1);
00722             }
00723 
00724 #endif /* ACE_LACKS_IOSTREAM_TOTALLY */
00725 
00726           ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER);
00727           ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM);
00728 
00729         }
00730       else if ((current_arg = arg_shifter.get_the_parameter
00731                 (ACE_LIB_TEXT("-ORBUseIMR"))))
00732         {
00733           // Use IR or not.
00734           this->use_implrepo_ = ACE_OS::atoi (current_arg);
00735 
00736           arg_shifter.consume_arg ();
00737         }
00738       else if ((current_arg = arg_shifter.get_the_parameter
00739                 (ACE_LIB_TEXT("-ORBid"))))
00740         {
00741           // The ORBid is actually set in ORB_init(), and then passed
00742           // to the TAO_ORB_Core() constructor.  However, in the case
00743           // where the ORBid third argument to ORB_init() is not zero,
00744           // any "-ORBid" arguments in the argv argument list are
00745           // supposed to be ignored, according to the CORBA spec.  As
00746           // such, "-ORBid" must be removed from the argument list
00747           // since ORB_init() must remove all "-ORB" option
00748           // arguments.
00749 
00750           // We obtain a lock on the ORB table when setting the
00751           // ORBid.  For this reason we should *not* set the ORBid
00752           // here.  CORBA::ORB_init() does all of the proper locking
00753           // and setting.
00754 
00755           arg_shifter.consume_arg ();
00756         }
00757       else if ((current_arg = arg_shifter.get_the_parameter
00758                 (ACE_LIB_TEXT("-ORBServerId"))))
00759         {
00760           // The this->server_id_ is to uniquely identify a server to
00761           // an IMR.
00762           // Fill in later.
00763           this->server_id_.set(ACE_TEXT_ALWAYS_CHAR(current_arg));
00764 
00765           arg_shifter.consume_arg ();
00766         }
00767       else if ((current_arg = arg_shifter.get_the_parameter
00768                 (ACE_LIB_TEXT("-ORBListenEndpoints"))))
00769         {
00770           // This option is similar to the -ORBEndPoint option. May be
00771           // ORBEndpoint option will be deprecated in future. But, for
00772           // now, I (Priyanka) am leaving so that both options can be
00773           // used.
00774 
00775           this->set_endpoint_helper (ACE_TEXT_ALWAYS_CHAR(current_arg)
00776                                      ACE_ENV_ARG_PARAMETER);
00777           ACE_CHECK_RETURN (-1);
00778 
00779           arg_shifter.consume_arg ();
00780         }
00781       else if ((current_arg = arg_shifter.get_the_parameter
00782                 (ACE_LIB_TEXT("-ORBNoProprietaryActivation"))))
00783         {
00784           // This option can be used to set to not use any proprietary
00785           // activation framework. The only TAO proprietary activation
00786           // framework is IMR. So, by setting this option in TAO, the
00787           // IMR shouldnt be used .. even if the ORBUseIMR option is
00788           // set.
00789           // Fill in later
00790           // @@ To do later: Priyanka.
00791 
00792           ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), -1);
00793         }
00794       else if ((current_arg = arg_shifter.get_the_parameter
00795                 (ACE_LIB_TEXT("-ORBSingleReadOptimization"))))
00796         {
00797           this->orb_params ()->single_read_optimization
00798             (ACE_OS::atoi (current_arg));
00799 
00800           arg_shifter.consume_arg ();
00801         }
00802       else if ((current_arg = arg_shifter.get_the_parameter
00803                 (ACE_LIB_TEXT("-ORBUseSharedProfile"))))
00804         {
00805           this->orb_params ()->shared_profile
00806             (ACE_OS::atoi (current_arg));
00807           arg_shifter.consume_arg ();
00808         }
00809       ////////////////////////////////////////////////////////////////
00810       // catch any unknown -ORB args                                //
00811       ////////////////////////////////////////////////////////////////
00812       else if (arg_shifter.cur_arg_strncasecmp (ACE_LIB_TEXT("-ORB")) != -1)
00813         {
00814           if (TAO_debug_level > 0)
00815             {
00816               current_arg = arg_shifter.get_current ();
00817               ACE_DEBUG ((LM_ERROR,
00818                           ACE_LIB_TEXT ("ERROR: Unknown \"-ORB\" option ")
00819                           ACE_LIB_TEXT ("<%s>.\n"),
00820                           ((current_arg == 0) ? ACE_LIB_TEXT("<NULL>") : current_arg)));
00821             }
00822 
00823           ACE_THROW_RETURN (CORBA::BAD_PARAM (
00824                               CORBA::SystemException::_tao_minor_code (
00825                                 TAO_ORB_CORE_INIT_LOCATION_CODE,
00826                                 EINVAL),
00827                               CORBA::COMPLETED_NO),
00828                             -1);
00829         }
00830 
00831       ////////////////////////////////////////////////////////////////
00832       // ok, we can't interpret this argument, move to next argument//
00833       ////////////////////////////////////////////////////////////////
00834       else
00835         // Any arguments that don't match are ignored so that the
00836         // caller can still use them.
00837         arg_shifter.ignore_arg ();
00838     }
00839 
00840 #if defined (SIGPIPE) && !defined (ACE_LACKS_UNIX_SIGNALS)
00841   // There's really no way to deal with this in a portable manner, so
00842   // we just have to suck it up and get preprocessor conditional and
00843   // ugly.
00844   //
00845   // Impractical to have each call to the ORB protect against the
00846   // implementation artifact of potential writes to dead connections,
00847   // as it'd be way expensive.  Do it here; who cares about SIGPIPE in
00848   // these kinds of applications, anyway?
00849   (void) ACE_OS::signal (SIGPIPE, (ACE_SignalHandler) SIG_IGN);
00850 #endif /* SIGPIPE */
00851 
00852   // Calling the open method here so that the svc.conf file is
00853   // opened and TAO_default_resource_factory::init () is called by the
00854   // time this method is called.
00855   this->parser_registry_.open (this);
00856 
00857   // Initialize the pointers to resources in the ORB Core instance,
00858   // e.g., reactor, connector, etc.  Must do this after we open
00859   // services because we'll load the factory from there.
00860   TAO_Resource_Factory *trf = this->resource_factory ();
00861 
00862   if (trf == 0)
00863     {
00864       ACE_ERROR ((LM_ERROR,
00865                   ACE_LIB_TEXT ("(%P|%t) %p\n"),
00866                   ACE_LIB_TEXT ("ORB Core unable to find a ")
00867                   ACE_LIB_TEXT ("Resource Factory instance")));
00868       ACE_THROW_RETURN (CORBA::INTERNAL (
00869                           CORBA::SystemException::_tao_minor_code (
00870                             TAO_ORB_CORE_INIT_LOCATION_CODE,
00871                             0),
00872                           CORBA::COMPLETED_NO),
00873                         -1);
00874     }
00875 
00876 
00877   this->codeset_manager_ = trf->get_codeset_manager();
00878   if (this->codeset_manager_ == 0)
00879     {
00880       ACE_ERROR ((LM_ERROR,
00881                   ACE_TEXT ("(%P|%t) %p\n"),
00882                   ACE_TEXT ("ORB Core unable to initialize codeset_manager")));
00883       ACE_THROW_RETURN (CORBA::INITIALIZE (
00884                           CORBA::SystemException::_tao_minor_code (
00885                             TAO_ORB_CORE_INIT_LOCATION_CODE,
00886                             0),
00887                           CORBA::COMPLETED_NO),
00888                         -1);
00889     }
00890 
00891   // @@ ????
00892   // Make sure the reactor is initialized...
00893   ACE_Reactor *reactor = this->reactor ();
00894   if (reactor == 0)
00895     {
00896       ACE_ERROR ((LM_ERROR,
00897                   ACE_LIB_TEXT ("(%P|%t) %p\n"),
00898                   ACE_LIB_TEXT ("ORB Core unable to initialize reactor")));
00899       ACE_THROW_RETURN (CORBA::INITIALIZE (
00900                           CORBA::SystemException::_tao_minor_code (
00901                             TAO_ORB_CORE_INIT_LOCATION_CODE,
00902                             0),
00903                           CORBA::COMPLETED_NO),
00904                         -1);
00905     }
00906 
00907   TAO_Server_Strategy_Factory *ssf = this->server_factory ();
00908 
00909   if (ssf == 0)
00910     {
00911       ACE_ERROR ((LM_ERROR,
00912                   ACE_LIB_TEXT ("(%P|%t) %p\n"),
00913                   ACE_LIB_TEXT ("ORB Core unable to find a ")
00914                   ACE_LIB_TEXT ("Server Strategy Factory instance")));
00915       ACE_THROW_RETURN (CORBA::INTERNAL (
00916                           CORBA::SystemException::_tao_minor_code (
00917                             TAO_ORB_CORE_INIT_LOCATION_CODE,
00918                             0),
00919                           CORBA::COMPLETED_NO),
00920                         -1);
00921     }
00922 
00923   ssf->open (this);
00924 
00925   // Obtain the timeout value for the thread-per-connection model
00926   this->thread_per_connection_use_timeout_ =
00927     ssf->thread_per_connection_timeout (this->thread_per_connection_timeout_);
00928 
00929   if (thread_per_connection_use_timeout_ == -1)
00930     {
00931       if (ACE_OS::strcasecmp (TAO_DEFAULT_THREAD_PER_CONNECTION_TIMEOUT,
00932                               "INFINITE") == 0)
00933         {
00934           this->thread_per_connection_use_timeout_ = 0;
00935         }
00936       else
00937         {
00938           this->thread_per_connection_use_timeout_ = 1;
00939           int milliseconds =
00940             ACE_OS::atoi (TAO_DEFAULT_THREAD_PER_CONNECTION_TIMEOUT);
00941           // Use a temporary to obtain automatic normalization.
00942           this->thread_per_connection_timeout_ =
00943             ACE_Time_Value (0, 1000 * milliseconds);
00944         }
00945     }
00946   if (this->thread_per_connection_use_timeout_ == 0)
00947     {
00948       // Do not wait for the server threads because they may block
00949       // forever.
00950       this->tm_.wait_on_exit (0);
00951     }
00952 
00953   // Initialize the "ORB" pseudo-object now.
00954   CORBA::ORB_ptr temp_orb = CORBA::ORB::_nil ();
00955 
00956   ACE_NEW_THROW_EX (temp_orb,
00957                     CORBA::ORB (this),
00958                     CORBA::NO_MEMORY (
00959                       CORBA::SystemException::_tao_minor_code (
00960                         TAO_ORB_CORE_INIT_LOCATION_CODE,
00961                         ENOMEM),
00962                       CORBA::COMPLETED_NO));
00963   ACE_CHECK_RETURN (-1);
00964 
00965   this->orb_ = temp_orb;
00966 
00967   // This should probably move into the ORB Core someday rather then
00968   // being done at this level.
00969   this->orb_->_use_omg_ior_format (use_ior);
00970 
00971   // Set all kinds of orb parameters whose setting needed to be
00972   // deferred until after the service config entries had been
00973   // determined.
00974 
00975   this->orb_params ()->service_port (NAMESERVICE, ns_port);
00976 
00977   if (ns_port != 0)
00978     {
00979       char ns_port_char[256];
00980 
00981       ACE_OS_String::itoa (ns_port,
00982                            ns_port_char,
00983                            10);
00984 
00985       CORBA::String_var ns_port_ptr =
00986         CORBA::string_alloc (ACE_static_cast(CORBA::ULong,
00987                                ACE_OS::strlen ((const char *) ns_port_char)));
00988 
00989       ns_port_ptr = (const char *) ns_port_char;
00990 
00991       const char prefix[] = "mcast://:";
00992 
00993       CORBA::String_var def_init_ref =
00994         CORBA::string_alloc (sizeof (prefix) +
00995                              ACE_static_cast(CORBA::ULong,
00996                                     ACE_OS::strlen (ns_port_ptr.in ())) +
00997                              2);
00998 
00999       ACE_OS::strcpy (def_init_ref.inout (), prefix);
01000       ACE_OS::strcat (def_init_ref.inout (), ns_port_ptr.in ());
01001       ACE_OS::strcat (def_init_ref.inout (), "::");
01002 
01003       this->orb_params ()->default_init_ref (def_init_ref.in ());
01004     }
01005 
01006   this->orb_params ()->service_port (TRADINGSERVICE, ts_port);
01007   this->orb_params ()->service_port (IMPLREPOSERVICE, ir_port);
01008 
01009   this->orb_params ()->use_dotted_decimal_addresses (dotted_decimal_addresses);
01010   this->orb_params ()->nodelay (nodelay);
01011   if (rcv_sock_size >= 0)
01012     this->orb_params ()->sock_rcvbuf_size (rcv_sock_size);
01013   if (snd_sock_size >= 0)
01014     this->orb_params ()->sock_sndbuf_size (snd_sock_size);
01015   if (cdr_tradeoff >= 0)
01016     this->orb_params ()->cdr_memcpy_tradeoff (cdr_tradeoff);
01017 
01018   this->orb_params ()->std_profile_components (std_profile_components);
01019 
01020   // Set up the pluggable protocol infrastructure.  First get a
01021   // pointer to the protocol factories set, then obtain pointers to
01022   // all factories loaded by the service configurator.
01023   // Load all protocol factories!
01024   if (trf->init_protocol_factories () == -1)
01025     ACE_THROW_RETURN (CORBA::INITIALIZE (
01026                         CORBA::SystemException::_tao_minor_code (
01027                           TAO_ORB_CORE_INIT_LOCATION_CODE,
01028                           0),
01029                         CORBA::COMPLETED_NO),
01030                       -1);
01031 
01032   // init the ORB core's pointer
01033   this->protocol_factories_ = trf->get_protocol_factories ();
01034 
01035   // Initialize the flushing strategy
01036   this->flushing_strategy_ = trf->create_flushing_strategy ();
01037 
01038   // Now that we have a complete list of available protocols and their
01039   // related factory objects, set default policies and initialize the
01040   // registries!
01041 
01042   // Set ORB-level policy defaults.
01043   TAO_Protocols_Hooks *tph =
01044     this->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER);
01045   ACE_CHECK_RETURN (-1);
01046 
01047   int status = tph->set_default_policies (ACE_ENV_SINGLE_ARG_PARAMETER);
01048   ACE_CHECK_RETURN (-1);
01049 
01050   if (status != 0)
01051     ACE_THROW_RETURN (CORBA::INITIALIZE (
01052                         CORBA::SystemException::_tao_minor_code (
01053                           TAO_ORB_CORE_INIT_LOCATION_CODE,
01054                           0),
01055                         CORBA::COMPLETED_NO),
01056                       -1);
01057 
01058 
01059   // Look for BiDirectional library here. If the user has svc.conf
01060   // file, load the library at this point.
01061   int ret = this->bidirectional_giop_init (ACE_ENV_SINGLE_ARG_PARAMETER);
01062   ACE_CHECK_RETURN (-1);
01063 
01064   if (ret == -1)
01065     return -1;
01066 
01067   // As a last step perform initializations of the service callbacks
01068   this->services_callbacks_init ();
01069 
01070   // The ORB has been initialized, meaning that the ORB is no longer
01071   // in the shutdown state.
01072   this->has_shutdown_ = 0;
01073 
01074   return 0;
01075 }
01076 
01077 
01078 int
01079 TAO_ORB_Core::fini (void)
01080 {
01081   ACE_TRY_NEW_ENV
01082     {
01083       // Shutdown the ORB and block until the shutdown is complete.
01084       this->shutdown (1
01085                       ACE_ENV_ARG_PARAMETER);
01086       ACE_TRY_CHECK;
01087     }
01088   ACE_CATCHANY
01089     {
01090       ACE_CString message =
01091         "Exception caught in trying to shutdown ";
01092       message += this->orbid_;
01093       message += "\n";
01094 
01095       ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION,
01096                            message.c_str ());
01097     }
01098   ACE_ENDTRY;
01099 
01100   // Wait for any server threads, ignoring any failures.
01101   (void) this->thr_mgr ()->wait ();
01102 
01103   CORBA::release (this->implrepo_service_);
01104 
01105   CORBA::release (this->typecode_factory_);
01106 
01107   CORBA::release (this->dynany_factory_);
01108 
01109   CORBA::release (this->ior_manip_factory_);
01110 
01111   CORBA::release (this->ior_table_);
01112 
01113   if (TAO_debug_level >= 3)
01114     {
01115       ACE_DEBUG ((LM_DEBUG,
01116                   ACE_LIB_TEXT ("Destroying ORB <%s>\n"),
01117                   this->orbid_));
01118     }
01119 
01120   // Finalize lane resources.
01121   //
01122   // @@ Do not call this->thread_lane_resources_manager().finalize().
01123   // this->thread_lane_manager_resources() can seg fault if the
01124   // factory method it invokes returns a zero pointer, which can
01125   // easily occur if the ORB is partially initialized due to a Service
01126   // Configurator initialization failure.  Instead check if the
01127   // cached pointer is non-zero and then finalize.
01128   //
01129   // @todo Fix potential seg fault in
01130   //       TAO_ORB_Core::thread_lane_resources_manager().
01131   if (this->thread_lane_resources_manager_ != 0)
01132     this->thread_lane_resources_manager_->finalize ();
01133 
01134   (void) TAO_Internal::close_services ();
01135 
01136 #if 0
01137   // @@todo: Need to go someday!
01138   if (this->message_block_dblock_allocator_)
01139     this->message_block_dblock_allocator_->remove ();
01140   delete this->message_block_dblock_allocator_;
01141 
01142   if (this-> message_block_buffer_allocator_)
01143     this->message_block_buffer_allocator_->remove ();
01144   delete this->message_block_buffer_allocator_;
01145 
01146   if (this->message_block_msgblock_allocator_)
01147     this->message_block_msgblock_allocator_->remove ();
01148   delete this->message_block_msgblock_allocator_;
01149 #endif /*if 0*/
01150 
01151   delete this;
01152 
01153   return 0;
01154 }
01155 
01156 void
01157 TAO_ORB_Core::set_thread_lane_resources_manager_factory (const char *thread_lane_resources_manager_factory_name)
01158 {
01159   TAO_ORB_Core_Static_Resources::instance ()->thread_lane_resources_manager_factory_name_ =
01160     thread_lane_resources_manager_factory_name;
01161 }
01162 
01163 void
01164 TAO_ORB_Core::set_collocation_resolver (const char *collocation_resolver_name)
01165 {
01166   TAO_ORB_Core_Static_Resources::instance ()->collocation_resolver_name_ =
01167     collocation_resolver_name;
01168 }
01169 
01170 void
01171 TAO_ORB_Core::set_stub_factory (const char *stub_factory_name)
01172 {
01173   TAO_ORB_Core_Static_Resources::instance ()->stub_factory_name_ =
01174     stub_factory_name;
01175 }
01176 
01177 void
01178 TAO_ORB_Core::set_resource_factory (const char *resource_factory_name)
01179 {
01180   TAO_ORB_Core_Static_Resources::instance ()->resource_factory_name_ =
01181     resource_factory_name;
01182 }
01183 
01184 void
01185 TAO_ORB_Core::dynamic_adapter_name (const char *name)
01186 {
01187   TAO_ORB_Core_Static_Resources::instance ()->dynamic_adapter_name_ = name;
01188 }
01189 
01190 const char *
01191 TAO_ORB_Core::dynamic_adapter_name (void)
01192 {
01193   return TAO_ORB_Core_Static_Resources::instance ()->dynamic_adapter_name_.c_str();
01194 }
01195 
01196 void
01197 TAO_ORB_Core::ifr_client_adapter_name (const char *name)
01198 {
01199   TAO_ORB_Core_Static_Resources::instance ()->ifr_client_adapter_name_ = name;
01200 }
01201 
01202 const char *
01203 TAO_ORB_Core::ifr_client_adapter_name (void)
01204 {
01205   return TAO_ORB_Core_Static_Resources::instance ()->ifr_client_adapter_name_.c_str();
01206 }
01207 
01208 void
01209 TAO_ORB_Core::typecodefactory_adapter_name (const char *name)
01210 {
01211   TAO_ORB_Core_Static_Resources::instance ()->typecodefactory_adapter_name_ = name;
01212 }
01213 
01214 const char *
01215 TAO_ORB_Core::typecodefactory_adapter_name (void)
01216 {
01217   return TAO_ORB_Core_Static_Resources::instance ()->typecodefactory_adapter_name_.c_str();
01218 }
01219 
01220 TAO_Resource_Factory *
01221 TAO_ORB_Core::resource_factory (void)
01222 {
01223   // Check if there is a cached reference.
01224   if (this->resource_factory_ != 0)
01225     return this->resource_factory_;
01226 
01227   // Look in the service repository for an instance.
01228   this->resource_factory_ =
01229     ACE_Dynamic_Service<TAO_Resource_Factory>::instance
01230     (TAO_ORB_Core_Static_Resources::instance ()->resource_factory_name_.c_str());
01231 
01232   return this->resource_factory_;
01233 }
01234 
01235 TAO_Thread_Lane_Resources_Manager &
01236 TAO_ORB_Core::thread_lane_resources_manager (void)
01237 {
01238   // Check if there is a cached reference.
01239   if (this->thread_lane_resources_manager_ != 0)
01240     return *this->thread_lane_resources_manager_;
01241 
01242   // If not, lookup the corresponding factory and ask it to make one.
01243   TAO_Thread_Lane_Resources_Manager_Factory *factory =
01244     ACE_Dynamic_Service<TAO_Thread_Lane_Resources_Manager_Factory>::instance
01245     (TAO_ORB_Core_Static_Resources::instance ()->thread_lane_resources_manager_factory_name_.c_str());
01246 
01247   this->thread_lane_resources_manager_ =
01248     factory->create_thread_lane_resources_manager (*this);
01249 
01250   return *this->thread_lane_resources_manager_;
01251 }
01252 
01253 TAO_Collocation_Resolver &
01254 TAO_ORB_Core::collocation_resolver (void)
01255 {
01256   // Check if there is a cached reference.
01257   if (this->collocation_resolver_ != 0)
01258     return *this->collocation_resolver_;
01259 
01260   // If not, lookup it up.
01261   this->collocation_resolver_ =
01262     ACE_Dynamic_Service<TAO_Collocation_Resolver>::instance
01263     (TAO_ORB_Core_Static_Resources::instance ()->collocation_resolver_name_.c_str());
01264 
01265   return *this->collocation_resolver_;
01266 }
01267 
01268 TAO_Stub_Factory *
01269 TAO_ORB_Core::stub_factory (void)
01270 {
01271   // Check if there is a cached reference.
01272   if (this->stub_factory_ != 0)
01273     return this->stub_factory_;
01274 
01275   // If not, look in the service repository for an instance.
01276   this->stub_factory_ =
01277     ACE_Dynamic_Service<TAO_Stub_Factory>::instance
01278     (TAO_ORB_Core_Static_Resources::instance ()->stub_factory_name_.c_str());
01279 
01280   return this->stub_factory_;
01281 }
01282 
01283 void
01284 TAO_ORB_Core::set_poa_factory (const char *poa_factory_name,
01285                                const char *poa_factory_directive)
01286 {
01287   TAO_ORB_Core_Static_Resources::instance ()->poa_factory_name_ =
01288     poa_factory_name;
01289   TAO_ORB_Core_Static_Resources::instance ()->poa_factory_directive_ =
01290     poa_factory_directive;
01291 }
01292 
01293 const ACE_CString &
01294 TAO_ORB_Core::poa_factory_name (void)
01295 {
01296   return TAO_ORB_Core_Static_Resources::instance ()->poa_factory_name_;
01297 }
01298 
01299 void
01300 TAO_ORB_Core::set_endpoint_selector_factory (const char *endpoint_selector_factory_name)
01301 {
01302   TAO_ORB_Core_Static_Resources::instance ()->endpoint_selector_factory_name_ =
01303     endpoint_selector_factory_name;
01304 }
01305 
01306 TAO_Endpoint_Selector_Factory *
01307 TAO_ORB_Core::endpoint_selector_factory (void)
01308 {
01309   // Check if there is a cached reference.
01310   if (this->endpoint_selector_factory_ != 0)
01311     return this->endpoint_selector_factory_;
01312 
01313   // If not, look in the service repository for an instance.
01314   this->endpoint_selector_factory_ =
01315     ACE_Dynamic_Service<TAO_Endpoint_Selector_Factory>::instance
01316     (TAO_ORB_Core_Static_Resources::instance ()->endpoint_selector_factory_name_.c_str());
01317 
01318   return this->endpoint_selector_factory_;
01319 }
01320 
01321 void
01322 TAO_ORB_Core::set_protocols_hooks (const char *protocols_hooks_name)
01323 {
01324   TAO_ORB_Core_Static_Resources::instance ()->protocols_hooks_name_ =
01325     protocols_hooks_name;
01326 }
01327 
01328 TAO_Protocols_Hooks *
01329 TAO_ORB_Core::get_protocols_hooks (ACE_ENV_SINGLE_ARG_DECL)
01330 {
01331   // Check if there is a cached reference.
01332   if (this->protocols_hooks_ != 0)
01333     return this->protocols_hooks_;
01334 
01335   // If not, look in the service repository for an instance.
01336   this->protocols_hooks_ =
01337     ACE_Dynamic_Service<TAO_Protocols_Hooks>::instance
01338     (TAO_ORB_Core_Static_Resources::instance ()->protocols_hooks_name_.c_str());
01339 
01340   // Initialize the protocols hooks instance.
01341   this->protocols_hooks_->init_hooks (this
01342                                       ACE_ENV_ARG_PARAMETER);
01343   ACE_CHECK_RETURN (0);
01344 
01345   return this->protocols_hooks_;
01346 }
01347 
01348 int
01349 TAO_ORB_Core::bidirectional_giop_init (ACE_ENV_SINGLE_ARG_DECL)
01350 {
01351   if (this->bidir_adapter_ == 0)
01352     {
01353       this->bidir_adapter_ =
01354         ACE_Dynamic_Service<TAO_BiDir_Adapter>::instance ("BiDirGIOP_Loader");
01355     }
01356 
01357   if (this->bidir_adapter_)
01358     return this->bidir_adapter_->activate (this->orb_.in (),
01359                                            0,
01360                                            0
01361                                            ACE_ENV_ARG_PARAMETER);
01362   else
01363     return 0;
01364 }
01365 
01366 void
01367 TAO_ORB_Core::services_callbacks_init (void)
01368 {
01369   // We (should) know what are the services that would need
01370   // callbacks. So, what we do is go through the Service Configurator
01371   // list for looking at the services that we want to load.
01372   this->ft_service_.init (this);
01373 
01374   // @@ Other service callbacks can be added here
01375 }
01376 
01377 int
01378 TAO_ORB_Core::service_raise_comm_failure (TAO_GIOP_Invocation *invoke,
01379                                           TAO_Profile *profile
01380                                           ACE_ENV_ARG_DECL)
01381 {
01382   if (this->ft_service_.service_callback ())
01383     {
01384       return this->ft_service_.service_callback ()->
01385                  raise_comm_failure (invoke,
01386                                      profile
01387                                      ACE_ENV_ARG_PARAMETER);
01388     }
01389 
01390   invoke->close_connection ();
01391 
01392   ACE_THROW_RETURN (CORBA::COMM_FAILURE (
01393       CORBA_SystemException::_tao_minor_code (
01394           TAO_INVOCATION_RECV_REQUEST_MINOR_CODE,
01395           errno),
01396       CORBA::COMPLETED_MAYBE),
01397       TAO_INVOKE_EXCEPTION);
01398 }
01399 
01400 int
01401 TAO_ORB_Core::service_raise_transient_failure (TAO_GIOP_Invocation *invoke,
01402                                                TAO_Profile *profile
01403                                                ACE_ENV_ARG_DECL)
01404 {
01405   if (this->ft_service_.service_callback ())
01406     {
01407       return this->ft_service_.service_callback ()->
01408                  raise_transient_failure (invoke,
01409                                           profile
01410                                           ACE_ENV_ARG_PARAMETER);
01411     }
01412 
01413   ACE_THROW_RETURN (CORBA::TRANSIENT (
01414         CORBA_SystemException::_tao_minor_code (
01415           TAO_INVOCATION_SEND_REQUEST_MINOR_CODE,
01416           errno),
01417         CORBA::COMPLETED_MAYBE),
01418         TAO_INVOKE_EXCEPTION);
01419 }
01420 
01421 
01422 void
01423 TAO_ORB_Core::service_context_list (
01424     TAO_Stub *stub,
01425     TAO_Service_Context &service_context,
01426     CORBA::Boolean restart
01427     ACE_ENV_ARG_DECL)
01428 {
01429   // @@ We look at the services if they are loaded. But if more
01430   // services offer this feature we may want to keep expanding the
01431   // 'if' conditions with a check for whether a service returned a
01432   // valid Policy object.
01433   if (this->ft_service_.service_callback ())
01434     {
01435       this->ft_service_.service_callback ()->service_context_list (stub,
01436                                                                    service_context.service_info (),
01437                                                                    restart
01438                                                                    ACE_ENV_ARG_PARAMETER);
01439       ACE_CHECK;
01440     }
01441 
01442   this->protocols_hooks_->rt_service_context (stub,
01443                                               service_context,
01444                                               restart
01445                                               ACE_ENV_ARG_PARAMETER);
01446   ACE_CHECK;
01447 }
01448 
01449 
01450 TAO_Client_Strategy_Factory *
01451 TAO_ORB_Core::client_factory (void)
01452 {
01453   if (this->client_factory_ == 0)
01454     {
01455       // Look in the service repository for an instance.
01456       this->client_factory_ =
01457         ACE_Dynamic_Service<TAO_Client_Strategy_Factory>::instance ("Client_Strategy_Factory");
01458     }
01459 
01460   return this->client_factory_;
01461 }
01462 
01463 TAO_Server_Strategy_Factory *
01464 TAO_ORB_Core::server_factory (void)
01465 {
01466   if (this->server_factory_ == 0)
01467     {
01468       // Look in the service repository for an instance.
01469       this->server_factory_ =
01470         ACE_Dynamic_Service<TAO_Server_Strategy_Factory>::instance ("Server_Strategy_Factory");
01471     }
01472 
01473   return this->server_factory_;
01474 }
01475 
01476 
01477 
01478 int
01479 TAO_ORB_Core::inherit_from_parent_thread (
01480   TAO_ORB_Core_TSS_Resources *tss_resources)
01481 {
01482   // Inherit properties/objects used in ORB_Core from the
01483   // parent thread.  Stuff inherited here must already exist
01484   // in the "parent" orbcore.
01485   // This is used in the thread-per-connection concurrency model where
01486   // each ORB spawned thread must use the resources of the spawning
01487   // thread...
01488 
01489   if (tss_resources == 0)
01490     return -1;
01491   return 0;
01492 }
01493 
01494 CORBA::Object_ptr
01495 TAO_ORB_Core::root_poa (ACE_ENV_SINGLE_ARG_DECL)
01496 {
01497   if (!CORBA::is_nil (this->root_poa_.in ()))
01498     return CORBA::Object::_duplicate (this->root_poa_.in ());
01499 
01500   TAO_ORB_Core_Static_Resources* static_resources =
01501     TAO_ORB_Core_Static_Resources::instance ();
01502   TAO_Adapter_Factory *factory =
01503     ACE_Dynamic_Service<TAO_Adapter_Factory>::instance (static_resources->poa_factory_name_.c_str());
01504   if (factory == 0)
01505     {
01506       ACE_Service_Config::process_directive (ACE_TEXT_CHAR_TO_TCHAR(static_resources->poa_factory_directive_.c_str()));
01507       factory =
01508         ACE_Dynamic_Service<TAO_Adapter_Factory>::instance (static_resources->poa_factory_name_.c_str());
01509     }
01510 
01511   if (factory == 0)
01512     {
01513       // It really failed, raise an exception!
01514       ACE_THROW_RETURN (CORBA::ORB::InvalidName (),
01515                         CORBA::Object::_nil ());
01516     }
01517 
01518   // @@ Not exception safe
01519   TAO_Adapter *poa_adapter = factory->create (this);
01520   poa_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER);
01521   ACE_CHECK_RETURN (CORBA::Object::_nil ());
01522 
01523   this->root_poa_ = poa_adapter->root ();
01524 
01525   this->adapter_registry_.insert (poa_adapter ACE_ENV_ARG_PARAMETER);
01526   ACE_CHECK_RETURN (CORBA::Object::_nil ());
01527 
01528   return CORBA::Object::_duplicate (this->root_poa_.in ());
01529 }
01530 
01531 TAO_Adapter *
01532 TAO_ORB_Core::poa_adapter (void)
01533 {
01534   if (this->poa_adapter_ == 0)
01535     {
01536       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
01537       if (this->poa_adapter_ == 0)
01538         {
01539           this->poa_adapter_ =
01540             this->adapter_registry_.find_adapter ("RootPOA");
01541         }
01542     }
01543   return this->poa_adapter_;
01544 }
01545 
01546 TAO_Stub *
01547 TAO_ORB_Core::create_stub (const char *repository_id,
01548                            const TAO_MProfile &profiles
01549                            ACE_ENV_ARG_DECL)
01550 {
01551   TAO_Stub *retval =
01552     this->stub_factory ()->create_stub (repository_id,
01553                                         profiles,
01554                                         this
01555                                         ACE_ENV_ARG_PARAMETER);
01556   ACE_CHECK_RETURN(0);
01557   return retval;
01558 }
01559 
01560 void
01561 TAO_ORB_Core::request_dispatcher (TAO_Request_Dispatcher *request_dispatcher)
01562 {
01563   // Assume ownership of the request dispatcher.
01564   TAO_Request_Dispatcher *tmp = this->request_dispatcher_;
01565   this->request_dispatcher_ = request_dispatcher;
01566   delete tmp;
01567 }
01568 
01569 TAO_Stub *
01570 TAO_ORB_Core::create_stub_object (TAO_MProfile &mprofile,
01571                                   const char *type_id,
01572                                   CORBA::PolicyList *policy_list
01573                                   ACE_ENV_ARG_DECL)
01574 {
01575   // Add the Polices contained in "policy_list" to each profile so
01576   // that those policies will be exposed to the client in the IOR.  In
01577   // particular each CORBA::Policy has to be converted in to
01578   // Messaging::PolicyValue, and then all the Messaging::PolicyValue
01579   // should be embedded inside a Messaging::PolicyValueSeq which
01580   // became in turns the "body" of the IOP::TaggedComponent. This
01581   // conversion is a responsability of the CORBA::Profile class.  (See
01582   // orbos\98-05-05.pdf Section 5.4)
01583   if (policy_list->length () != 0)
01584     {
01585       TAO_Profile * profile;
01586 
01587       for (CORBA::ULong i = 0; i < mprofile.profile_count (); ++i)
01588         {
01589           // Get the ith profile
01590           profile = mprofile.get_profile (i);
01591           profile->policies (policy_list TAO_ENV_ARG_PARAMETER);
01592           ACE_CHECK_RETURN (0);
01593         }
01594     }
01595 
01596   /// Initialize a TAO_Stub object with the mprofile thats passed.
01597   TAO_Stub *stub =
01598     this->create_stub (type_id, mprofile ACE_ENV_ARG_PARAMETER);
01599   ACE_CHECK_RETURN (stub);
01600 
01601   stub->base_profiles ().policy_list (policy_list);
01602 
01603   return stub;
01604 }
01605 
01606 void
01607 TAO_ORB_Core::load_policy_validators (TAO_Policy_Validator &validator)
01608 {
01609   // Call the BiDir library if it has been loaded
01610   if (this->bidir_adapter_)
01611     this->bidir_adapter_->load_policy_validators (validator);
01612 }
01613 
01614 CORBA::Object_ptr
01615 TAO_ORB_Core::create_object (TAO_Stub *stub)
01616 {
01617   // @@ What about forwarding.  With this approach we are never forwarded
01618   //    when we use collocation!
01619   const TAO_MProfile &mprofile = stub->base_profiles ();
01620 
01621   {
01622     // @@ Ossama: maybe we need another lock for the table, to
01623     //    reduce contention on the Static_Object_Lock below, if so
01624     //    then we need to use that lock in the ORB_init() function.
01625     ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard,
01626                               *ACE_Static_Object_Lock::instance (),
01627                               0));
01628 
01629     TAO_ORB_Table *table = TAO_ORB_Table::instance ();
01630     TAO_ORB_Table::Iterator end = table->end ();
01631     for (TAO_ORB_Table::Iterator i = table->begin ();
01632          i != end;
01633          ++i)
01634       {
01635         TAO_ORB_Core *other_core = (*i).int_id_;
01636         CORBA::Object_ptr x =
01637           this->create_collocated_object (stub,
01638                                           other_core,
01639                                           mprofile);
01640         if (x != 0)
01641           return x;
01642       }
01643   }
01644 
01645   // @@ We should thow CORBA::NO_MEMORY in platforms with exceptions,
01646   // but we are stuck in platforms without exceptions!
01647   CORBA::Object_ptr x;
01648 
01649   // The constructor sets the proxy broker as the
01650   // Remote one.
01651   ACE_NEW_RETURN (x,
01652                   CORBA_Object (stub, 0),
01653                   0);
01654   return x;
01655 }
01656 
01657 CORBA::Object_ptr
01658 TAO_ORB_Core::create_collocated_object (TAO_Stub *stub,
01659                                         TAO_ORB_Core *orb_core,
01660                                         const TAO_MProfile &mprofile)
01661 {
01662   if (!orb_core->optimize_collocation_objects ())
01663     return 0;
01664 
01665   if (!orb_core->use_global_collocation () && orb_core != this)
01666     return 0;
01667 
01668   if (!orb_core->is_collocated (mprofile))
01669     return 0;
01670 
01671   // OK, the target ORB and the mprofile match, use the Adapter
01672   // Registry of each ORB to find the right one.
01673 
01674   return orb_core->adapter_registry ()->create_collocated_object (stub,
01675                                                                   mprofile);
01676 }
01677 
01678 int
01679 TAO_ORB_Core::is_collocated (const TAO_MProfile& mprofile)
01680 {
01681   // @@ Lots of issues arise when dealing with collocation.  What about
01682   //    forwarding or what if this is a multi-profile IOR where the order is
01683   //    significant and only one of the profiles is collocated.  For example
01684   //    when using a multiple servers for fault tolerance.  For now, we just
01685   //    look through all profiles and if any are colocated then we assume
01686   //    the object is collocated.
01687   // @@ Note, if collocated we can not be forwarded!
01688   //    Also, acceptor_registry_->is_collocated (...) will check the
01689   //    address (ORB Host) but not the object_key.  This should be checked
01690   //    also.
01691 
01692   return this->thread_lane_resources_manager ().is_collocated (mprofile);
01693 }
01694 
01695 // ****************************************************************
01696 
01697 TAO_Leader_Follower &
01698 TAO_ORB_Core::leader_follower (void)
01699 {
01700   return this->lane_resources ().leader_follower ();
01701 }
01702 
01703 TAO_LF_Strategy &
01704 TAO_ORB_Core::lf_strategy (void)
01705 {
01706   return this->thread_lane_resources_manager ().lf_strategy ();
01707 }
01708 
01709 int
01710 TAO_ORB_Core::run (ACE_Time_Value *tv,
01711                    int perform_work
01712                    ACE_ENV_ARG_DECL_NOT_USED)
01713 {
01714   if (TAO_debug_level >= 3)
01715     ACE_DEBUG ((LM_DEBUG,
01716                 "TAO (%P|%t) - ORB_Core::run, "
01717                 "start [%s]\n",
01718                 perform_work?"perform_work":"run"));
01719 
01720   // Fetch the Reactor
01721   ACE_Reactor *r = this->reactor ();
01722 
01723   int result = 1;
01724   // 1 to detect that nothing went wrong
01725 
01726   // Loop handling client requests until the ORB is shutdown.
01727 
01728   // We could use the leader-follower lock to check for the state
01729   // if this variable or use the lock <create_event_loop_lock> in
01730   // the server strategy factory.
01731   // We don't need to do this because we use the Reactor
01732   // mechanisms to shutdown in a thread-safe way.
01733 
01734   while (this->has_shutdown () == 0)
01735     {
01736       // Every time we perform an interation we have to become the
01737       // leader again, because it is possible that a client has
01738       // acquired the leader role...
01739       TAO_Leader_Follower &leader_follower =
01740         this->leader_follower ();
01741 
01742       TAO_LF_Strategy &lf_strategy =
01743         this->lf_strategy ();
01744 
01745       TAO_LF_Event_Loop_Thread_Helper helper (leader_follower,
01746                                               lf_strategy,
01747                                               tv);
01748       int result = helper.event_loop_return ();
01749       if (result != 0)
01750         {
01751           if (errno == ETIME)
01752             return 0;
01753           else
01754             return result;
01755         }
01756 
01757       // Set the owning thread of the Reactor to the one which we're
01758       // currently in.  This is necessary b/c it's possible that the
01759       // application is calling us from a thread other than that in which
01760       // the Reactor's CTOR (which sets the owner) was called.
01761       //
01762       // We need to do this on every iteration because the reactor may be
01763       // acquired by one of the client threads in the LF waiting
01764       // strategy
01765       r->owner (ACE_Thread::self ());
01766 
01767       if (TAO_debug_level >= 3)
01768         ACE_DEBUG ((LM_DEBUG,
01769                     ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, "
01770                                   "calling handle_events()\n")));
01771 
01772       result = r->handle_events (tv);
01773 
01774       if (TAO_debug_level >= 3)
01775         ACE_DEBUG ((LM_DEBUG,
01776                     ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, "
01777                                   "handle_events() returns %d\n"),
01778                     result));
01779 
01780       if (result == -1)
01781         {
01782           // An error, terminate the loop
01783           break;
01784         }
01785       if (result == 0
01786           && tv != 0
01787           && *tv == ACE_Time_Value::zero)
01788         {
01789           // A timeout, terminate the loop...
01790           break;
01791         }
01792       if (perform_work)
01793         {
01794           // This is running on behalf of a perform_work() call,
01795           // The loop should run only once.
01796           break;
01797         }
01798       // Otherwise just continue..
01799     }
01800 
01801   if (TAO_debug_level >= 3)
01802     ACE_DEBUG ((LM_DEBUG,
01803                 ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, ")
01804                 ACE_LIB_TEXT ("ends with result = %d\n"),
01805                 result));
01806 
01807   return result;
01808 }
01809 
01810 
01811 void
01812 TAO_ORB_Core::shutdown (CORBA::Boolean wait_for_completion
01813                         ACE_ENV_ARG_DECL)
01814   ACE_THROW_SPEC (())
01815 {
01816   ACE_TRY
01817     {
01818       {
01819         ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_);
01820 
01821         if (this->has_shutdown () != 0)
01822           return;
01823 
01824         // Check if we are on the right state, i.e. do not accept
01825         // shutdowns with the 'wait_for_completion' flag set in the middle
01826         // of an upcall (because those deadlock).
01827         this->adapter_registry_.check_close (wait_for_completion
01828                                              ACE_ENV_ARG_PARAMETER);
01829         ACE_TRY_CHECK;
01830 
01831         // Set the 'has_shutdown' flag, so any further attempt to shutdown
01832         // becomes a noop.
01833         this->has_shutdown_ = 1;
01834 
01835         // need to release the mutex, because some of the shutdown
01836         // operations invoke application code, that could (and in practice
01837         // does!) callback into ORB Core code.
01838       }
01839 
01840       this->adapter_registry_.close (wait_for_completion
01841                                      ACE_ENV_ARG_PARAMETER);
01842       ACE_TRY_CHECK;
01843 
01844       // Shutdown reactor.
01845       this->thread_lane_resources_manager ().shutdown_reactor ();
01846 
01847       // Grab the thread manager
01848       ACE_Thread_Manager *tm = this->thr_mgr ();
01849 
01850       // Try to cancel all the threads in the ORB.
01851       tm->cancel_all ();
01852 
01853       // If <wait_for_completion> is set, wait for all threads to exit.
01854       if (wait_for_completion != 0)
01855         tm->wait ();
01856 
01857       // Invoke Interceptor::destroy() on all registered interceptors.
01858       this->destroy_interceptors (ACE_ENV_SINGLE_ARG_PARAMETER);
01859       ACE_TRY_CHECK;
01860 
01861       // Explicitly destroy the object reference table since it
01862       // contains references to objects, which themselves may contain
01863       // reference to this ORB.
01864       this->object_ref_table_.destroy ();
01865 
01866 #if (TAO_HAS_INTERCEPTORS == 1)
01867       this->pi_current_ = 0;  // For the sake of consistency.
01868 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
01869     }
01870   ACE_CATCHALL
01871     {
01872       // Do not allow exceptions to escape.. So catch all the
01873       // exceptions.
01874       // @@ Not sure what to print here for the users..
01875 
01876     }
01877   ACE_ENDTRY;
01878 
01879   return;
01880 }
01881 
01882 void
01883 TAO_ORB_Core::destroy (ACE_ENV_SINGLE_ARG_DECL)
01884 {
01885   //
01886   // All destroy() should do is (a) call shutdown() and (b) unbind()
01887   // from the ORB table.  Nothing else should really be added to this
01888   // method.  Everything else should go to the shutdown() method.
01889   // Remember when the ORB Core is finally removed from the ORB table,
01890   // the reference count goes to zero and fini() is called.  fini()
01891   // calls shutdown() and does not call destroy() since destroy() will
01892   // try to unbind from the ORB table again.  Additional code should
01893   // not be added to destroy() since there is no guarantee that
01894   // orb->destroy() will ever be called by the user.  Since TAO
01895   // guarantees that shutdown() will be called, all cleanup code
01896   // should go there.
01897   //
01898 
01899   // Shutdown the ORB and block until the shutdown is complete.
01900   this->shutdown (1
01901                   ACE_ENV_ARG_PARAMETER);
01902   ACE_CHECK;
01903 
01904   // Now remove it from the ORB table so that it's ORBid may be
01905   // reused.
01906   {
01907     ACE_MT (ACE_GUARD (TAO_SYNCH_RECURSIVE_MUTEX, guard,
01908                        *ACE_Static_Object_Lock::instance ()));
01909     TAO_ORB_Table::instance ()->unbind (this->orbid_);
01910   }
01911 }
01912 
01913 void
01914 TAO_ORB_Core::destroy_interceptors (ACE_ENV_SINGLE_ARG_DECL)
01915   ACE_THROW_SPEC (())
01916 {
01917   size_t len = 0;   // The length of the interceptor array.
01918   size_t ilen = 0;  // The incremental length of the interceptor array.
01919 
01920   ACE_TRY
01921     {
01922 #if TAO_HAS_INTERCEPTORS == 1
01923       TAO_ClientRequestInterceptor_List::TYPE &client_interceptors =
01924         this->client_request_interceptors_.interceptors ();
01925 
01926       len = client_interceptors.size ();
01927       ilen = len;
01928       for (size_t i = 0; i < len; ++i)
01929         {
01930           // Destroy the interceptors in reverse order in case the array
01931           // list is only partially destroyed and another invocation
01932           // occurs afterwards.
01933           --ilen;
01934 
01935           client_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
01936           ACE_TRY_CHECK;
01937 
01938           // Since Interceptor::destroy() can throw an exception, decrease
01939           // the size of the interceptor array incrementally since some
01940           // interceptors may not have been destroyed yet.  Note that this
01941           // size reduction is fast since no memory is actually
01942           // deallocated.
01943           client_interceptors.size (ilen);
01944         }
01945 
01946       TAO_ServerRequestInterceptor_List::TYPE &server_interceptors =
01947         this->server_request_interceptors_.interceptors ();
01948 
01949       len = server_interceptors.size ();
01950       ilen = len;
01951       for (size_t j = 0; j < len; ++j)
01952         {
01953           // Destroy the interceptors in reverse order in case the array
01954           // list is only partially destroyed and another invocation
01955           // occurs afterwards.
01956           --ilen;
01957 
01958           server_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
01959           ACE_TRY_CHECK;
01960 
01961           // Since Interceptor::destroy() can throw an exception, decrease
01962           // the size of the interceptor array incrementally since some
01963           // interceptors may not have been destroyed yet.  Note that this
01964           // size reduction is fast since no memory is actually
01965           // deallocated.
01966           server_interceptors.size (ilen);
01967         }
01968 
01969 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
01970 
01971       TAO_IORInterceptor_List::TYPE &ior_interceptors =
01972         this->ior_interceptors_.interceptors ();
01973 
01974       len = ior_interceptors.size ();
01975       ilen = len;
01976       for (size_t k = 0; k < len; ++k)
01977         {
01978           // Destroy the interceptors in reverse order in case the array
01979           // list is only partially destroyed and another invocation
01980           // occurs afterwards.
01981           --ilen;
01982 
01983           ior_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
01984           ACE_TRY_CHECK;
01985 
01986           // Since Interceptor::destroy() can throw an exception, decrease
01987           // the size of the interceptor array incrementally since some
01988           // interceptors may not have been destroyed yet.  Note that this
01989           // size reduction is fast since no memory is actually
01990           // deallocated.
01991           ior_interceptors.size (ilen);
01992         }
01993     }
01994   ACE_CATCHALL
01995     {
01996       // .. catch all the exceptions..
01997       if (TAO_debug_level > 3)
01998         ACE_DEBUG ((LM_DEBUG,
01999                     ACE_LIB_TEXT ("(%P|%t) Exception in TAO_ORB_Core::destroy_interceptors () \n")));
02000     }
02001   ACE_ENDTRY;
02002 
02003   return;
02004 }
02005 
02006 TAO_Thread_Lane_Resources &
02007 TAO_ORB_Core::lane_resources (void)
02008 {
02009   return this->thread_lane_resources_manager ().lane_resources ();
02010 }
02011 
02012 void
02013 TAO_ORB_Core::resolve_typecodefactory_i (ACE_ENV_SINGLE_ARG_DECL)
02014 {
02015   TAO_Object_Loader *loader =
02016     ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TypeCodeFactory_Loader");
02017   if (loader == 0)
02018     {
02019       ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic TypeCodeFactory Service_Object *")
02020                                              ACE_LIB_TEXT("TAO_TypeCodeFactory:_make_TAO_TypeCodeFactory_Loader()"));
02021       loader =
02022         ACE_Dynamic_Service<TAO_Object_Loader>::instance ("TypeCodeFactory_Loader");
02023       if (loader == 0)
02024         ACE_THROW (CORBA::ORB::InvalidName ());
02025     }
02026   this->typecode_factory_ =
02027     loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER);
02028 }
02029 
02030 void
02031 TAO_ORB_Core::resolve_dynanyfactory_i (ACE_ENV_SINGLE_ARG_DECL)
02032 {
02033   TAO_Object_Loader *loader =
02034     ACE_Dynamic_Service<TAO_Object_Loader>::instance ("DynamicAny_Loader");
02035   if (loader == 0)
02036     {
02037       ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic DynamicAny_Loader Service_Object *")
02038                                              ACE_LIB_TEXT("TAO_DynamicAny:_make_TAO_DynamicAny_Loader()"));
02039       loader =
02040         ACE_Dynamic_Service<TAO_Object_Loader>::instance ("DynamicAny_Loader");
02041       if (loader == 0)
02042         ACE_THROW (CORBA::ORB::InvalidName ());
02043     }
02044   this->dynany_factory_ =
02045     loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER);
02046 }
02047 
02048 void
02049 TAO_ORB_Core::resolve_iormanipulation_i (ACE_ENV_SINGLE_ARG_DECL)
02050 {
02051   TAO_Object_Loader *loader =
02052     ACE_Dynamic_Service<TAO_Object_Loader>::instance ("IORManip_Loader");
02053 
02054   if (loader == 0)
02055     {
02056       ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic IORManip_Loader Service_Object *")
02057                                              ACE_LIB_TEXT("TAO_IORManip:_make_TAO_IORManip_Loader()"));
02058       loader =
02059         ACE_Dynamic_Service<TAO_Object_Loader>::instance ("IORManip_Loader");
02060       if (loader == 0)
02061         ACE_THROW (CORBA::ORB::InvalidName ());
02062     }
02063   this->ior_manip_factory_ =
02064     loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER);
02065 }
02066 
02067 void
02068 TAO_ORB_Core::resolve_ior_table_i (ACE_ENV_SINGLE_ARG_DECL)
02069 {
02070   TAO_Adapter_Factory *factory =
02071     ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ("TAO_IORTable");
02072   if (factory == 0)
02073     {
02074       ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic TAO_IORTable Service_Object *")
02075                                              ACE_LIB_TEXT("TAO_IORTable:_make_TAO_Table_Adapter_Factory()"));
02076       factory =
02077         ACE_Dynamic_Service<TAO_Adapter_Factory>::instance ("TAO_IORTable");
02078     }
02079   if (factory == 0)
02080     ACE_THROW (CORBA::ORB::InvalidName ());
02081 
02082   // @@ Not exception safe
02083   TAO_Adapter *iortable_adapter = factory->create (this);
02084   this->adapter_registry_.insert (iortable_adapter ACE_ENV_ARG_PARAMETER);
02085   ACE_CHECK;
02086 
02087   iortable_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER);
02088   ACE_CHECK;
02089 
02090   this->ior_table_ = iortable_adapter->root ();
02091 }
02092 
02093 int
02094 TAO_ORB_Core::set_endpoint_helper (const char *current_arg
02095                                    ACE_ENV_ARG_DECL)
02096 {
02097   ACE_CString endpts (current_arg);
02098 
02099   if (this->orb_params ()->endpoints (endpts) != 0)
02100     {
02101       ACE_ERROR ((LM_ERROR,
02102                   ACE_LIB_TEXT ("(%P|%t)\n")
02103                   ACE_LIB_TEXT ("Invalid endpoint(s) specified:\n%s\n"),
02104                   ACE_TEXT_CHAR_TO_TCHAR(endpts.c_str ())));
02105       ACE_THROW_RETURN (CORBA::BAD_PARAM (
02106                            CORBA::SystemException::_tao_minor_code (
02107                               TAO_ORB_CORE_INIT_LOCATION_CODE,
02108                               EINVAL),
02109                            CORBA::COMPLETED_NO),
02110                         -1);
02111     }
02112 
02113   return 0;
02114 }
02115 
02116 CORBA::Object_ptr
02117 TAO_ORB_Core::resolve_rir (const char *name
02118                            ACE_ENV_ARG_DECL)
02119 {
02120   // Get the table of initial references specified through
02121   // -ORBInitRef.
02122   ACE_CString ior;
02123   ACE_CString object_id ((const char *) name);
02124 
02125   // Get the list of initial reference prefixes specified through
02126   // -ORBDefaultInitRef.
02127   CORBA::String_var default_init_ref =
02128     this->orb_params ()->default_init_ref ();
02129 
02130   // Check if a DefaultInitRef was specified.
02131   if (ACE_OS::strlen (default_init_ref.in ()) != 0)
02132     {
02133       static const char corbaloc_prefix[] = "corbaloc:";
02134       static const char mcast_prefix[] = "mcast:";
02135       char object_key_delimiter = 0;
02136 
02137       ACE_CString list_of_profiles (default_init_ref.in ());
02138 
02139       // Check if the protocol is corbaloc: or mcast:.
02140       // If it is, set the object_key_delimiter.
02141       if ((ACE_OS::strncmp (default_init_ref.in (),
02142                             corbaloc_prefix,
02143                             sizeof corbaloc_prefix -1) == 0) ||
02144           (ACE_OS::strncmp (default_init_ref.in (),
02145                             mcast_prefix,
02146                             sizeof mcast_prefix -1) == 0))
02147         {
02148           object_key_delimiter = '/';
02149         }
02150       else
02151         {
02152           TAO_Connector_Registry *conn_reg =
02153             this->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER);
02154           ACE_CHECK_RETURN (0);
02155 
02156           // Obtain the appropriate object key delimiter for the
02157           // specified protocol.
02158           object_key_delimiter =
02159             conn_reg->object_key_delimiter (list_of_profiles.c_str ());
02160         }
02161 
02162       // Make sure that the default initial reference doesn't end
02163       // with the object key delimiter character.
02164       if (list_of_profiles[list_of_profiles.length() - 1] !=
02165           object_key_delimiter)
02166             list_of_profiles += ACE_CString (object_key_delimiter);
02167 
02168       list_of_profiles += object_id;
02169 
02170       return this->orb ()->string_to_object (list_of_profiles.c_str ()
02171                                              ACE_ENV_ARG_PARAMETER);
02172     }
02173 
02174   return CORBA::Object::_nil ();
02175 }
02176 
02177 CORBA::ORB::ObjectIdList_ptr
02178 TAO_ORB_Core::list_initial_references (ACE_ENV_SINGLE_ARG_DECL)
02179 {
02180   // Unsupported initial services should NOT be included in the below list!
02181   const char *initial_services[] = { TAO_LIST_OF_INITIAL_SERVICES };
02182   // Make sure the "terminating" zero is the last array element so
02183   // that there is a stop condition when iterating through the list.
02184 
02185   const size_t initial_services_size =
02186     sizeof (initial_services) / sizeof (initial_services[0]);
02187 
02188   const size_t total_size =
02189     initial_services_size
02190     + this->init_ref_map_.current_size ()
02191     + this->object_ref_table_.current_size ();
02192 
02193   CORBA::ORB::ObjectIdList_ptr tmp = 0;
02194 
02195   ACE_NEW_THROW_EX (tmp,
02196                     CORBA_ORB_ObjectIdList (
02197                       ACE_static_cast(CORBA::ULong, total_size)),
02198                     CORBA::NO_MEMORY ());
02199   ACE_CHECK_RETURN (0);
02200 
02201   CORBA::ORB::ObjectIdList_var list = tmp;
02202   list->length (ACE_static_cast(CORBA::ULong, total_size));
02203 
02204   CORBA::ULong index = 0;
02205   // Index for ObjectIdList members.
02206 
02207   // Iterate over the registered initial references.
02208   for (index = 0; index < initial_services_size; ++index)
02209     list[index] = initial_services[index];
02210 
02211   // Now iterate over the initial references created by the user and
02212   // add them to the sequence.
02213 
02214   // References registered via
02215   // ORBInitInfo::register_initial_reference().
02216   TAO_Object_Ref_Table::Iterator obj_ref_end =
02217     this->object_ref_table_.end ();
02218 
02219   for (TAO_Object_Ref_Table::Iterator i = this->object_ref_table_.begin ();
02220        i != obj_ref_end;
02221        ++i, ++index)
02222     list[index] = CORBA::string_dup ((*i).ext_id_);
02223 
02224   // References registered via INS.
02225   InitRefMap::iterator end = this->init_ref_map_.end ();
02226 
02227   for (InitRefMap::iterator j = this-> init_ref_map_.begin ();
02228        j != end;
02229        ++j, ++index)
02230     list[index] = (*j).ext_id_.c_str ();
02231 
02232   return list._retn ();
02233 }
02234 
02235 // ****************************************************************
02236 ACE_Allocator*
02237 TAO_ORB_Core::input_cdr_dblock_allocator (void)
02238 {
02239   return this->lane_resources ().input_cdr_dblock_allocator ();
02240 }
02241 
02242 ACE_Allocator*
02243 TAO_ORB_Core::input_cdr_buffer_allocator (void)
02244 {
02245   return this->lane_resources ().input_cdr_buffer_allocator ();
02246 }
02247 
02248 ACE_Allocator*
02249 TAO_ORB_Core::input_cdr_msgblock_allocator (void)
02250 {
02251   return this->lane_resources ().input_cdr_msgblock_allocator ();
02252 }
02253 
02254 ACE_Allocator*
02255 TAO_ORB_Core::output_cdr_dblock_allocator (void)
02256 {
02257 
02258   // Allocating memory here confuses purify a bit. We do delete this
02259   // memory when TSS delete
02260   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
02261   if (tss == 0)
02262     ACE_ERROR_RETURN ((LM_ERROR,
02263                        ACE_LIB_TEXT ("(%P|%t) %p\n"),
02264                        ACE_LIB_TEXT ("TAO_ORB_Core::output_cdr_dblock_allocator (); ")
02265                        ACE_LIB_TEXT ("no more TSS keys")),
02266                       0);
02267 
02268   if (tss->output_cdr_dblock_allocator_ == 0)
02269     tss->output_cdr_dblock_allocator_ =
02270       this->resource_factory ()->output_cdr_dblock_allocator ();
02271 
02272   return tss->output_cdr_dblock_allocator_;
02273 }
02274 
02275 ACE_Allocator*
02276 TAO_ORB_Core::output_cdr_buffer_allocator (void)
02277 {
02278   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
02279   if (tss == 0)
02280     ACE_ERROR_RETURN ((LM_ERROR,
02281                        ACE_LIB_TEXT ("(%P|%t) %p\n"),
02282                        ACE_LIB_TEXT ("TAO_ORB_Core::input_cdr_buffer_allocator (); ")
02283                        ACE_LIB_TEXT ("no more TSS keys")),
02284                       0);
02285 
02286   if (tss->output_cdr_buffer_allocator_ == 0)
02287     tss->output_cdr_buffer_allocator_ =
02288       this->resource_factory ()->output_cdr_buffer_allocator ();
02289 
02290   return tss->output_cdr_buffer_allocator_;
02291 }
02292 
02293 
02294 ACE_Allocator*
02295 TAO_ORB_Core::output_cdr_msgblock_allocator (void)
02296 {
02297   TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources ();
02298   if (tss == 0)
02299     ACE_ERROR_RETURN ((LM_ERROR,
02300                        ACE_LIB_TEXT ("(%P|%t) %p\n"),
02301                        ACE_LIB_TEXT ("TAO_ORB_Core::output_cdr_msgblock_allocator (); ")
02302                        ACE_LIB_TEXT ("no more TSS keys")),
02303                       0);
02304 
02305   if (tss->output_cdr_msgblock_allocator_ == 0)
02306     tss->output_cdr_msgblock_allocator_ =
02307       this->resource_factory ()->output_cdr_msgblock_allocator ();
02308 
02309   return tss->output_cdr_msgblock_allocator_;
02310 }
02311 
02312 
02313 ACE_Allocator *
02314 TAO_ORB_Core::transport_message_buffer_allocator (void)
02315 {
02316   return this->lane_resources ().transport_message_buffer_allocator ();
02317 }
02318 
02319 
02320 ACE_Data_Block*
02321 TAO_ORB_Core::create_input_cdr_data_block (size_t size)
02322 {
02323 
02324   ACE_Allocator *dblock_allocator;
02325   ACE_Allocator *buffer_allocator;
02326 
02327   dblock_allocator =
02328     this->input_cdr_dblock_allocator ();
02329   buffer_allocator =
02330     this->input_cdr_buffer_allocator ();
02331 
02332   ACE_Lock* lock_strategy = 0;
02333   if (this->resource_factory ()->use_locked_data_blocks ())
02334     {
02335       lock_strategy = &this->data_block_lock_;
02336     }
02337 
02338   return this->create_data_block_i (size,
02339                                     buffer_allocator,
02340                                     dblock_allocator,
02341                                     lock_strategy);
02342 }
02343 
02344 #if 0
02345 // @@todo: This will go off after sometime. We may no longer need
02346 // this, since we could as well use the input_cdr* for use.
02347 
02348 ACE_Data_Block *
02349 TAO_ORB_Core::data_block_for_message_block (size_t size)
02350 {
02351 
02352   ACE_Allocator *dblock_allocator;
02353   ACE_Allocator *buffer_allocator;
02354 
02355   dblock_allocator =
02356     this->message_block_dblock_allocator ();
02357   buffer_allocator =
02358     this->message_block_buffer_allocator ();
02359 
02360   ACE_Lock* lock_strategy = 0;
02361   if (this->resource_factory ()->use_locked_data_blocks ())
02362     {
02363       lock_strategy = &this->data_block_lock_;
02364     }
02365 
02366   return this->create_data_block_i (size,
02367                                     buffer_allocator,
02368                                     dblock_allocator,
02369                                     lock_strategy);
02370 }
02371 
02372 ACE_Allocator*
02373 TAO_ORB_Core::message_block_dblock_allocator (void)
02374 {
02375   if (this->message_block_dblock_allocator_ == 0)
02376     {
02377       // Double checked locking
02378       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
02379       if (this->message_block_dblock_allocator_ == 0)
02380         this->message_block_dblock_allocator_ =
02381           this->resource_factory ()->input_cdr_dblock_allocator ();
02382     }
02383   return this->message_block_dblock_allocator_;
02384 }
02385 
02386 ACE_Allocator*
02387 TAO_ORB_Core::message_block_buffer_allocator (void)
02388 {
02389   if (this->message_block_buffer_allocator_ == 0)
02390     {
02391       // Double checked locking
02392       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
02393       if (this->message_block_buffer_allocator_ == 0)
02394         this->message_block_buffer_allocator_ =
02395           this->resource_factory ()->input_cdr_buffer_allocator ();
02396     }
02397   return this->message_block_buffer_allocator_;
02398 }
02399 
02400 ACE_Allocator*
02401 TAO_ORB_Core::message_block_msgblock_allocator (void)
02402 {
02403   if (this->message_block_msgblock_allocator_ == 0)
02404     {
02405       // Double checked locking
02406       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
02407       if (this->message_block_msgblock_allocator_ == 0)
02408         this->message_block_msgblock_allocator_ =
02409           this->resource_factory ()->input_cdr_buffer_allocator ();
02410     }
02411   return this->message_block_msgblock_allocator_;
02412 }
02413 
02414 #endif /*if 0*/
02415 
02416 ACE_Data_Block *
02417 TAO_ORB_Core::create_data_block_i (size_t size,
02418                                    ACE_Allocator *buffer_allocator,
02419                                    ACE_Allocator *dblock_allocator,
02420                                    ACE_Lock *lock_strategy)
02421 {
02422   ACE_Data_Block *nb = 0;
02423 
02424   ACE_NEW_MALLOC_RETURN (
02425                          nb,
02426                          ACE_static_cast(ACE_Data_Block*,
02427                                          dblock_allocator->malloc (sizeof (ACE_Data_Block))),
02428                          ACE_Data_Block (size,
02429                                          ACE_Message_Block::MB_DATA,
02430                                          0,
02431                                          buffer_allocator,
02432                                          lock_strategy,
02433                                          0,
02434                                          dblock_allocator),
02435                          0);
02436 
02437   return nb;
02438 }
02439 
02440 TAO_Connector_Registry *
02441 TAO_ORB_Core::connector_registry (ACE_ENV_SINGLE_ARG_DECL)
02442 {
02443   TAO_Connector_Registry *conn =
02444     this->lane_resources ().connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER);
02445   ACE_CHECK_RETURN (0);
02446 
02447   return conn;
02448 }
02449 
02450 ACE_Reactor *
02451 TAO_ORB_Core::reactor (void)
02452 {
02453   return this->leader_follower ().reactor ();
02454 }
02455 
02456 CORBA::Object_ptr
02457 TAO_ORB_Core::implrepo_service (void)
02458 {
02459   if (!this->use_implrepo_)
02460     return CORBA::Object::_nil ();
02461 
02462   if (CORBA::is_nil (this->implrepo_service_))
02463     {
02464 
02465       ACE_TRY_NEW_ENV
02466         {
02467           CORBA::Object_var temp = this->orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER);
02468           ACE_TRY_CHECK;
02469 
02470           ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, CORBA::Object::_nil ());
02471 
02472           // @@ Worry about assigning a different IOR? (brunsch)
02473           this->implrepo_service_ = temp._retn ();
02474         }
02475       ACE_CATCHANY
02476         {
02477           // Just make sure that we have a null pointer.  Ignore the exception anyway.
02478           this->implrepo_service_ = CORBA::Object::_nil ();
02479         }
02480       ACE_ENDTRY;
02481     }
02482 
02483   return CORBA::Object::_duplicate (this->implrepo_service_);
02484 }
02485 
02486 void
02487 TAO_ORB_Core::call_sync_scope_hook (TAO_Stub *stub,
02488                                     int &has_synchronization,
02489                                     Messaging::SyncScope &scope)
02490 {
02491   Sync_Scope_Hook sync_scope_hook =
02492     TAO_ORB_Core_Static_Resources::instance ()->sync_scope_hook_;
02493 
02494   if (sync_scope_hook == 0)
02495     {
02496       has_synchronization = 0;
02497       return;
02498     }
02499 
02500   (*sync_scope_hook) (this, stub, has_synchronization, scope);
02501 }
02502 
02503 TAO_Sync_Strategy &
02504 TAO_ORB_Core::get_sync_strategy (TAO_Stub *,
02505                                  Messaging::SyncScope &scope)
02506 {
02507 
02508   if (scope == Messaging::SYNC_WITH_TRANSPORT
02509       || scope == Messaging::SYNC_WITH_SERVER
02510       || scope == Messaging::SYNC_WITH_TARGET)
02511     return this->transport_sync_strategy ();
02512 
02513 #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1)
02514 
02515   if (scope == Messaging::SYNC_NONE
02516       || scope == TAO::SYNC_EAGER_BUFFERING)
02517     return this->eager_buffering_sync_strategy ();
02518 
02519   if (scope == TAO::SYNC_DELAYED_BUFFERING)
02520     return this->delayed_buffering_sync_strategy ();
02521 
02522 #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */
02523 
02524   return this->transport_sync_strategy ();
02525 }
02526 
02527 void
02528 TAO_ORB_Core::set_sync_scope_hook (Sync_Scope_Hook hook)
02529 {
02530   TAO_ORB_Core_Static_Resources::instance ()-> sync_scope_hook_ = hook;
02531 }
02532 
02533 #if (TAO_HAS_SYNC_SCOPE_POLICY == 1)
02534 
02535 CORBA::Policy_ptr
02536 TAO_ORB_Core::stubless_sync_scope (void)
02537 {
02538   CORBA::Policy_var result;
02539 
02540   // No need to lock, the object is in TSS storage....
02541   TAO_Policy_Current &policy_current =
02542     this->policy_current ();
02543   result = policy_current.get_cached_policy (TAO_CACHED_POLICY_SYNC_SCOPE);
02544 
02545   // @@ Must lock, but is is harder to implement than just modifying
02546   //    this call: the ORB does take a lock to modify the policy
02547   //    manager
02548   if (CORBA::is_nil (result.in ()))
02549     {
02550       TAO_Policy_Manager *policy_manager =
02551         this->policy_manager ();
02552       if (policy_manager != 0)
02553         result = policy_manager->get_cached_policy (
02554                    TAO_CACHED_POLICY_SYNC_SCOPE);
02555     }
02556 
02557   if (CORBA::is_nil (result.in ()))
02558     result = this->default_policies_->get_cached_policy (
02559                TAO_CACHED_POLICY_SYNC_SCOPE);
02560 
02561   return result._retn ();
02562 }
02563 
02564 #endif /* TAO_HAS_SYNC_SCOPE_POLICY == 1 */
02565 
02566 void
02567 TAO_ORB_Core::call_timeout_hook (TAO_Stub *stub,
02568                                  int &has_timeout,
02569                                  ACE_Time_Value &time_value)
02570 {
02571   Timeout_Hook timeout_hook =
02572     TAO_ORB_Core_Static_Resources::instance ()->timeout_hook_;
02573 
02574   if (timeout_hook == 0)
02575     {
02576       has_timeout = 0;
02577       return;
02578     }
02579   (*timeout_hook) (this, stub, has_timeout, time_value);
02580 }
02581 
02582 void
02583 TAO_ORB_Core::set_timeout_hook (Timeout_Hook hook)
02584 {
02585   TAO_ORB_Core_Static_Resources::instance ()->timeout_hook_ = hook;
02586   // Saving the hook pointer so that we can use it later when needed.
02587 
02588   return;
02589 }
02590 
02591 CORBA::Policy_ptr
02592 TAO_ORB_Core::stubless_relative_roundtrip_timeout (void)
02593 {
02594   CORBA::Policy_var result;
02595 
02596 #if (TAO_HAS_CORBA_MESSAGING == 1 \
02597      && TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1)
02598 
02599   // No need to lock, the object is in TSS storage....
02600   TAO_Policy_Current &policy_current =
02601     this->policy_current ();
02602   result = policy_current.get_cached_policy (
02603              TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT);
02604 
02605   // @@ Must lock, but is is harder to implement than just modifying
02606   //    this call: the ORB does take a lock to modify the policy
02607   //    manager
02608   if (CORBA::is_nil (result.in ()))
02609     {
02610       TAO_Policy_Manager *policy_manager =
02611         this->policy_manager ();
02612       if (policy_manager != 0)
02613         result = policy_manager->get_cached_policy (
02614           TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT);
02615     }
02616 
02617   if (CORBA::is_nil (result.in ()))
02618     result = this->default_policies_->get_cached_policy (
02619                TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT);
02620 
02621 #endif /* TAO_HAS_CORBA_MESSAGING == 1
02622           && TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1 */
02623 
02624   return result._retn ();
02625 }
02626 
02627 
02628 void
02629 TAO_ORB_Core::connection_timeout (TAO_Stub *stub,
02630                                   int &has_timeout,
02631                                   ACE_Time_Value &time_value)
02632 {
02633   Timeout_Hook connection_timeout_hook =
02634     TAO_ORB_Core_Static_Resources::instance ()->connection_timeout_hook_;
02635 
02636   if (connection_timeout_hook == 0)
02637     {
02638       has_timeout = 0;
02639       return;
02640     }
02641   (*connection_timeout_hook) (this, stub, has_timeout, time_value);
02642 }
02643 
02644 void
02645 TAO_ORB_Core::connection_timeout_hook (Timeout_Hook hook)
02646 {
02647   // Saving the hook pointer so that we can use it later when needed.
02648   TAO_ORB_Core_Static_Resources::instance ()->connection_timeout_hook_ = hook;
02649 }
02650 
02651 CORBA::Policy_ptr
02652 TAO_ORB_Core::stubless_connection_timeout (void)
02653 {
02654   CORBA::Policy_var result;
02655 
02656 #if (TAO_HAS_CORBA_MESSAGING == 1 \
02657      && TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1)
02658 
02659   // No need to lock, the object is in TSS storage....
02660   TAO_Policy_Current &policy_current =
02661     this->policy_current ();
02662   result = policy_current.get_cached_policy (
02663              TAO_CACHED_POLICY_CONNECTION_TIMEOUT);
02664 
02665   // @@ Must lock, but is is harder to implement than just modifying
02666   //    this call: the ORB does take a lock to modify the policy
02667   //    manager
02668   if (CORBA::is_nil (result.in ()))
02669     {
02670       TAO_Policy_Manager *policy_manager =
02671         this->policy_manager ();
02672       if (policy_manager != 0)
02673         result = policy_manager->get_cached_policy (
02674           TAO_CACHED_POLICY_CONNECTION_TIMEOUT);
02675     }
02676 
02677   if (CORBA::is_nil (result.in ()))
02678     result = this->default_policies_->get_cached_policy (
02679                TAO_CACHED_POLICY_CONNECTION_TIMEOUT);
02680 
02681 #endif /* TAO_HAS_CORBA_MESSAGING == 1
02682           && TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1 */
02683 
02684   return result._retn ();
02685 }
02686 
02687 
02688 #if (TAO_HAS_CORBA_MESSAGING == 1)
02689 
02690 CORBA::Policy_ptr
02691 TAO_ORB_Core::get_cached_policy (TAO_Cached_Policy_Type type)
02692 {
02693   CORBA::Policy_var result;
02694 
02695   // @@ Must lock, but is is harder to implement than just modifying
02696   //    this call: the ORB does take a lock to modify the policy
02697   //    manager
02698   TAO_Policy_Manager *policy_manager =
02699     this->policy_manager ();
02700   if (policy_manager != 0)
02701     result = policy_manager->get_cached_policy (type);
02702 
02703   if (CORBA::is_nil (result.in ()))
02704     result = this->get_default_policies ()->get_cached_policy (type);
02705 
02706   return result._retn ();
02707 }
02708 
02709 #endif /* (TAO_HAS_CORBA_MESSAGING == 1) */
02710 
02711 // ****************************************************************
02712 
02713 TAO_ORB_Core_TSS_Resources::TAO_ORB_Core_TSS_Resources (void)
02714   : output_cdr_dblock_allocator_ (0),
02715     output_cdr_buffer_allocator_ (0),
02716     output_cdr_msgblock_allocator_ (0),
02717     event_loop_thread_ (0),
02718     client_leader_thread_ (0),
02719     lane_ (0),
02720     ts_objects_ (),
02721     orb_core_ (0)
02722 #if TAO_HAS_INTERCEPTORS == 1
02723     , pi_current_ ()
02724     , client_request_info_ (0)
02725 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
02726 {
02727 #if TAO_HAS_INTERCEPTORS == 1
02728   ACE_NEW (this->client_request_info_,
02729            TAO_ClientRequestInfo);
02730 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
02731 }
02732 
02733 TAO_ORB_Core_TSS_Resources::~TAO_ORB_Core_TSS_Resources (void)
02734 {
02735   if (this->output_cdr_dblock_allocator_ != 0)
02736     this->output_cdr_dblock_allocator_->remove ();
02737   delete this->output_cdr_dblock_allocator_;
02738 
02739   if (this->output_cdr_buffer_allocator_ != 0)
02740     this->output_cdr_buffer_allocator_->remove ();
02741   delete this->output_cdr_buffer_allocator_;
02742 
02743   if (this->output_cdr_msgblock_allocator_ != 0)
02744     this->output_cdr_msgblock_allocator_->remove ();
02745   delete this->output_cdr_msgblock_allocator_;
02746 
02747 #if TAO_HAS_INTERCEPTORS == 1
02748   CORBA::release (this->client_request_info_);
02749 #endif  /* TAO_HAS_INTERCEPTORS == 1 */
02750 
02751   //@@ This is broken on platforms that use TSS emulation since this
02752   //   destructor is invoked after the ORB.  Since we're under
02753   //   pressure to release a beta, we'll have to leak the TSS objects
02754   //   stores in the <ts_objects_> array.  However, the only service
02755   //   known to currently use this array is the SSLIOP pluggable
02756   //   protocol.  Fortunately, it registeres a null cleanup function
02757   //   so we're not leaking anything yet.  We *do* need to fix this
02758   //   before other services start to use this array.
02759   //      -Ossama
02760   // if (this->orb_core_ != 0)
02761   //   this->orb_core_->tss_cleanup_funcs ()->cleanup (this->ts_objects_);
02762 }
02763 
02764 // ****************************************************************
02765 
02766 TAO_TSS_Resources::TAO_TSS_Resources (void)
02767   :  poa_current_impl_ (0),
02768      default_environment_ (&this->tss_environment_)
02769 
02770 #if (TAO_HAS_CORBA_MESSAGING == 1)
02771 
02772   , policy_current_ (&this->initial_policy_current_)
02773 
02774 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
02775 
02776 {
02777 }
02778 
02779 TAO_TSS_Resources::~TAO_TSS_Resources (void)
02780 {
02781 }
02782 
02783 // ****************************************************************
02784 
02785 TAO_Export TAO_ORB_Core *
02786 TAO_ORB_Core_instance (void)
02787 {
02788   // @@ This is a slight violation of layering, we should use
02789   //    TAO_ORB_Core_instance(), but that breaks during startup.
02790   TAO_ORB_Table *orb_table = TAO_ORB_Table::instance ();
02791   if (orb_table->first_orb () == 0)
02792     {
02793       ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard,
02794                                 *ACE_Static_Object_Lock::instance (), 0));
02795 
02796       if (orb_table->first_orb () == 0)
02797         {
02798           // Calling CORBA::ORB_init() returns a duplicated ORB
02799           // reference, so make sure that reference is stored in an
02800           // ORB_var so that no leak occurs.  The duplicate ORB
02801           // reference isn't needed outside the scope of this function
02802           // since the corresponding ORB Core instance will still
02803           // exist in the ORB table after the ORB reference is
02804           // destroyed.
02805 
02806           CORBA::ORB_var orb;
02807 
02808           int argc = 0;
02809           ACE_DECLARE_NEW_CORBA_ENV;
02810           ACE_TRY
02811             {
02812               orb = CORBA::ORB_init (argc, 0, 0 ACE_ENV_ARG_PARAMETER);
02813               ACE_TRY_CHECK;
02814             }
02815           ACE_CATCHANY
02816             {
02817               // @@ What should we do here?
02818             }
02819           ACE_ENDTRY;
02820         }
02821     }
02822 
02823   return orb_table->first_orb ();
02824 }
02825 
02826 
02827 int
02828 TAO_ORB_Core::collocation_strategy (CORBA::Object_ptr object
02829                                     ACE_ENV_ARG_DECL)
02830 {
02831 
02832   TAO_Stub *stub = object->_stubobj ();
02833   if (!CORBA::is_nil (stub->servant_orb_var ().in ()) &&
02834       stub->servant_orb_var ()->orb_core () != 0)
02835     {
02836       TAO_ORB_Core *orb_core =
02837         stub->servant_orb_var ()->orb_core ();
02838 
02839       int collocated =
02840         orb_core->collocation_resolver ().is_collocated (object
02841                                                          ACE_ENV_ARG_PARAMETER);
02842       ACE_CHECK_RETURN (-1);
02843 
02844       if (collocated)
02845         {
02846           switch (stub->servant_orb_var ()->orb_core ()->get_collocation_strategy ())
02847             {
02848             case THRU_POA:
02849               return TAO_Collocation_Strategies::CS_THRU_POA_STRATEGY;
02850 
02851             case DIRECT:
02852               {
02853                 /////////////////////////////////////////////////////////////
02854                 // If the servant is null and you are collocated this means
02855                 // that the POA policy NON-RETAIN is set, and with that policy
02856                 // using the DIRECT collocation strategy is just insane.
02857                 /////////////////////////////////////////////////////////////
02858                 ACE_ASSERT (object->_servant () != 0);
02859                 return TAO_Collocation_Strategies::CS_DIRECT_STRATEGY;
02860               }
02861             }
02862         }
02863     }
02864 
02865   // In this case the Object is a client.
02866   return TAO_Collocation_Strategies::CS_REMOTE_STRATEGY;
02867 }
02868 
02869 TAO_ORB_Core::InitRefMap *
02870 TAO_ORB_Core::init_ref_map ()
02871 {
02872   return &this->init_ref_map_;
02873 }
02874 
02875 void
02876 TAO_ORB_Core::set_default (const char *orb_id)
02877 {
02878   TAO_ORB_Table *table = TAO_ORB_Table::instance ();
02879   table->set_default (orb_id);
02880 }
02881 
02882 void
02883 TAO_ORB_Core::not_default (const char *orb_id)
02884 {
02885   TAO_ORB_Table *table = TAO_ORB_Table::instance ();
02886   table->not_default (orb_id);
02887 }
02888 
02889 // ****************************************************************
02890 
02891 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
02892 
02893 template class ACE_Lock_Adapter<ACE_Null_Mutex>;
02894 #if defined (ACE_HAS_THREADS)
02895 template class ACE_Lock_Adapter<TAO_SYNCH_RECURSIVE_MUTEX>;
02896 template class ACE_Lock_Adapter<TAO_SYNCH_MUTEX>;
02897 #endif /* ACE_HAS_THREADS */
02898 
02899 template class ACE_Reverse_Lock<TAO_SYNCH_MUTEX>;
02900 template class ACE_Guard<ACE_Reverse_Lock<TAO_SYNCH_MUTEX> >;
02901 
02902 template class TAO_TSS_Singleton<TAO_TSS_Resources, TAO_SYNCH_MUTEX>;
02903 template class ACE_TSS<TAO_TSS_Resources>;
02904 template class ACE_TSS<TAO_ORB_Core_TSS_Resources>;
02905 
02906 template class ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
02907 template class ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
02908 template class ACE_Hash_Map_Entry<ACE_CString, ACE_CString>;
02909 template class ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
02910 template class ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>;
02911 
02912 template class ACE_Array_Base<void *>;
02913 
02914 template class ACE_Dynamic_Service<TAO_Server_Strategy_Factory>;
02915 template class ACE_Dynamic_Service<TAO_Client_Strategy_Factory>;
02916 
02917 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
02918 
02919 #pragma instantiate ACE_Lock_Adapter<ACE_Null_Mutex>
02920 #if defined (ACE_HAS_THREADS)
02921 #pragma instantiate ACE_Lock_Adapter<TAO_SYNCH_RECURSIVE_MUTEX>
02922 #pragma instantiate ACE_Lock_Adapter<TAO_SYNCH_MUTEX>
02923 #endif /* ACE_HAS_THREADS */
02924 
02925 #pragma instantiate ACE_Reverse_Lock<TAO_SYNCH_MUTEX>
02926 #pragma instantiate ACE_Guard<ACE_Reverse_Lock<TAO_SYNCH_MUTEX> >
02927 
02928 #pragma instantiate TAO_TSS_Singleton<TAO_TSS_Resources, TAO_SYNCH_MUTEX>
02929 #pragma instantiate ACE_TSS<TAO_TSS_Resources>
02930 #pragma instantiate ACE_TSS<TAO_ORB_Core_TSS_Resources>
02931 
02932 #pragma instantiate ACE_Hash_Map_Manager_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
02933 #pragma instantiate ACE_Hash_Map_Iterator_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
02934 #pragma instantiate ACE_Hash_Map_Entry<ACE_CString, ACE_CString>
02935 #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
02936 #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex<ACE_CString, ACE_CString, ACE_Hash<ACE_CString>, ACE_Equal_To<ACE_CString>, ACE_Null_Mutex>
02937 
02938 #pragma instantiate ACE_Array_Base<void *>
02939 
02940 #pragma instantiate ACE_Dynamic_Service<TAO_Server_Strategy_Factory>
02941 #pragma instantiate ACE_Dynamic_Service<TAO_Client_Strategy_Factory>
02942 
02943 #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

Generated on Mon Jun 16 13:49:11 2003 for TAO by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002