Thread_Lane_Resources.cpp

Go to the documentation of this file.
00001 // $Id: Thread_Lane_Resources.cpp 79169 2007-08-02 08:41:23Z johnnyw $
00002 
00003 #include "tao/Thread_Lane_Resources.h"
00004 
00005 ACE_RCSID (tao,
00006            Thread_Lane_Resources,
00007            "$Id: Thread_Lane_Resources.cpp 79169 2007-08-02 08:41:23Z johnnyw $")
00008 
00009 #include "tao/Acceptor_Registry.h"
00010 #include "tao/LF_Follower.h"
00011 #include "tao/Leader_Follower.h"
00012 #include "tao/Connection_Handler.h"
00013 #include "tao/Transport.h"
00014 #include "tao/Connector_Registry.h"
00015 #include "tao/SystemException.h"
00016 #include "tao/ORB_Core.h"
00017 
00018 #include "ace/Reactor.h"
00019 
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 TAO_Thread_Lane_Resources::TAO_Thread_Lane_Resources (
00024     TAO_ORB_Core &orb_core,
00025     TAO_New_Leader_Generator *new_leader_generator
00026   )
00027   : orb_core_ (orb_core),
00028     acceptor_registry_ (0),
00029     connector_registry_ (0),
00030     transport_cache_ (0),
00031     leader_follower_ (0),
00032     new_leader_generator_ (new_leader_generator),
00033     input_cdr_dblock_allocator_ (0),
00034     input_cdr_buffer_allocator_ (0),
00035     input_cdr_msgblock_allocator_ (0),
00036     transport_message_buffer_allocator_ (0),
00037     output_cdr_dblock_allocator_ (0),
00038     output_cdr_buffer_allocator_ (0),
00039     output_cdr_msgblock_allocator_ (0),
00040     amh_response_handler_allocator_ (0),
00041     ami_response_handler_allocator_ (0)
00042 {
00043   // Create the transport cache.
00044   ACE_NEW (this->transport_cache_,
00045            TAO::Transport_Cache_Manager (orb_core));
00046 
00047 }
00048 
00049 TAO_Thread_Lane_Resources::~TAO_Thread_Lane_Resources (void)
00050 {
00051 
00052 }
00053 
00054 TAO::Transport_Cache_Manager &
00055 TAO_Thread_Lane_Resources::transport_cache (void)
00056 {
00057   return *this->transport_cache_;
00058 }
00059 
00060 int
00061 TAO_Thread_Lane_Resources::has_acceptor_registry_been_created (void) const
00062 {
00063   return this->acceptor_registry_ != 0;
00064 }
00065 
00066 int
00067 TAO_Thread_Lane_Resources::is_collocated (const TAO_MProfile& mprofile)
00068 {
00069   if (!this->has_acceptor_registry_been_created ())
00070     {
00071       return 0;
00072     }
00073 
00074   return this->acceptor_registry ().is_collocated (mprofile);
00075 }
00076 
00077 TAO_Acceptor_Registry &
00078 TAO_Thread_Lane_Resources::acceptor_registry (void)
00079 {
00080   // Double check.
00081   if (this->acceptor_registry_ == 0)
00082     {
00083       // @todo: Wouldnt this crash big time if you happen to
00084       // dereference a null-pointer? Needs fixing.
00085       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00086                         ace_mon,
00087                         this->lock_,
00088                         *this->acceptor_registry_);
00089 
00090       if (this->acceptor_registry_ == 0)
00091         {
00092           // @@ Not exception safe code
00093           // Get the resource factory.
00094           TAO_Resource_Factory &resource_factory =
00095             *this->orb_core_.resource_factory ();
00096 
00097           // Ask it to create a new acceptor registry.
00098           this->acceptor_registry_ =
00099             resource_factory.get_acceptor_registry ();
00100         }
00101     }
00102 
00103   return *this->acceptor_registry_;
00104 }
00105 
00106 TAO_Connector_Registry *
00107 TAO_Thread_Lane_Resources::connector_registry (void)
00108 {
00109   // Double check.
00110   if (this->connector_registry_ == 0)
00111     {
00112       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00113                         ace_mon,
00114                         this->lock_,
00115                         0);
00116 
00117       if (this->connector_registry_ == 0)
00118         {
00119           // Ask it to create a new acceptor registry.
00120           TAO_Connector_Registry *connector_registry =
00121             this->orb_core_.resource_factory ()->get_connector_registry ();
00122 
00123           if (connector_registry == 0)
00124             {
00125               throw ::CORBA::INITIALIZE (
00126                 CORBA::SystemException::_tao_minor_code (
00127                   TAO_CONNECTOR_REGISTRY_INIT_LOCATION_CODE,
00128                   0),
00129                 CORBA::COMPLETED_NO);
00130             }
00131 
00132           if (connector_registry->open (&this->orb_core_) != 0)
00133             {
00134               throw ::CORBA::INITIALIZE (
00135                 CORBA::SystemException::_tao_minor_code (
00136                   TAO_CONNECTOR_REGISTRY_INIT_LOCATION_CODE,
00137                   0),
00138                 CORBA::COMPLETED_NO);
00139             }
00140 
00141           // Finally, everything is created and opened successfully:
00142           // now we can assign to the member.  Otherwise, the
00143           // assignment would be premature.
00144           this->connector_registry_ = connector_registry;
00145         }
00146     }
00147 
00148   return this->connector_registry_;
00149 }
00150 
00151 
00152 TAO_Leader_Follower &
00153 TAO_Thread_Lane_Resources::leader_follower (void)
00154 {
00155   // Double check.
00156   if (this->leader_follower_ == 0)
00157     {
00158       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00159                         ace_mon,
00160                         this->lock_,
00161                         *this->leader_follower_);
00162 
00163       if (this->leader_follower_ == 0)
00164         {
00165           // Create a new Leader Follower object.
00166           ACE_NEW_RETURN (this->leader_follower_,
00167                           TAO_Leader_Follower (&this->orb_core_,
00168                                                this->new_leader_generator_),
00169                           *this->leader_follower_);
00170         }
00171     }
00172 
00173   return *this->leader_follower_;
00174 }
00175 
00176 
00177 ACE_Allocator*
00178 TAO_Thread_Lane_Resources::input_cdr_dblock_allocator (void)
00179 {
00180   if (this->input_cdr_dblock_allocator_ == 0)
00181     {
00182       // Double checked locking
00183       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00184 
00185       if (this->input_cdr_dblock_allocator_ == 0)
00186         {
00187           this->input_cdr_dblock_allocator_ =
00188             this->resource_factory ()->input_cdr_dblock_allocator ();
00189         }
00190     }
00191 
00192   return this->input_cdr_dblock_allocator_;
00193 }
00194 
00195 
00196 ACE_Allocator*
00197 TAO_Thread_Lane_Resources::input_cdr_buffer_allocator (void)
00198 {
00199   if (this->input_cdr_buffer_allocator_ == 0)
00200     {
00201       // Double checked locking
00202       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00203 
00204       if (this->input_cdr_buffer_allocator_ == 0)
00205         {
00206           this->input_cdr_buffer_allocator_ =
00207             this->resource_factory ()->input_cdr_buffer_allocator ();
00208         }
00209     }
00210 
00211   return this->input_cdr_buffer_allocator_;
00212 }
00213 
00214 
00215 ACE_Allocator*
00216 TAO_Thread_Lane_Resources::input_cdr_msgblock_allocator (void)
00217 {
00218   if (this->input_cdr_msgblock_allocator_ == 0)
00219     {
00220       // Double checked locking
00221       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00222 
00223       if (this->input_cdr_msgblock_allocator_ == 0)
00224         {
00225           this->input_cdr_msgblock_allocator_ =
00226             this->resource_factory ()->input_cdr_msgblock_allocator ();
00227         }
00228     }
00229 
00230   return this->input_cdr_msgblock_allocator_;
00231 }
00232 
00233 ACE_Allocator*
00234 TAO_Thread_Lane_Resources::transport_message_buffer_allocator (void)
00235 {
00236   if (this->transport_message_buffer_allocator_ == 0)
00237     {
00238       // Double checked locking
00239       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00240 
00241       if (this->transport_message_buffer_allocator_ == 0)
00242         {
00243           this->transport_message_buffer_allocator_ =
00244             this->resource_factory ()->input_cdr_dblock_allocator ();
00245         }
00246     }
00247 
00248   return this->transport_message_buffer_allocator_;
00249 }
00250 
00251 
00252 ACE_Allocator*
00253 TAO_Thread_Lane_Resources::output_cdr_dblock_allocator (void)
00254 {
00255   if (this->output_cdr_dblock_allocator_ == 0)
00256     {
00257       // Double checked locking
00258       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00259 
00260       if (this->output_cdr_dblock_allocator_ == 0)
00261         {
00262           this->output_cdr_dblock_allocator_ =
00263             this->resource_factory ()->output_cdr_dblock_allocator ();
00264         }
00265     }
00266 
00267   return this->output_cdr_dblock_allocator_;
00268 }
00269 
00270 
00271 ACE_Allocator*
00272 TAO_Thread_Lane_Resources::output_cdr_buffer_allocator (void)
00273 {
00274   if (this->output_cdr_buffer_allocator_ == 0)
00275     {
00276       // Double checked locking
00277       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00278 
00279       if (this->output_cdr_buffer_allocator_ == 0)
00280         {
00281           this->output_cdr_buffer_allocator_ =
00282             this->resource_factory ()->output_cdr_buffer_allocator ();
00283         }
00284     }
00285 
00286   return this->output_cdr_buffer_allocator_;
00287 }
00288 
00289 
00290 ACE_Allocator*
00291 TAO_Thread_Lane_Resources::output_cdr_msgblock_allocator (void)
00292 {
00293   if (this->output_cdr_msgblock_allocator_ == 0)
00294     {
00295       // Double checked locking
00296       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00297 
00298       if (this->output_cdr_msgblock_allocator_ == 0)
00299         {
00300           this->output_cdr_msgblock_allocator_ =
00301             this->resource_factory ()->output_cdr_msgblock_allocator ();
00302         }
00303     }
00304 
00305   return this->output_cdr_msgblock_allocator_;
00306 }
00307 
00308 ACE_Allocator*
00309 TAO_Thread_Lane_Resources::amh_response_handler_allocator (void)
00310 {
00311   if (this->amh_response_handler_allocator_ == 0)
00312     {
00313       // Double checked locking
00314       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00315 
00316       if (this->amh_response_handler_allocator_ == 0)
00317         {
00318           this->amh_response_handler_allocator_ =
00319             this->resource_factory ()->amh_response_handler_allocator ();
00320         }
00321     }
00322 
00323   return this->amh_response_handler_allocator_;
00324 }
00325 
00326 ACE_Allocator*
00327 TAO_Thread_Lane_Resources::ami_response_handler_allocator (void)
00328 {
00329   if (this->ami_response_handler_allocator_ == 0)
00330     {
00331       // Double checked locking
00332       ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0);
00333 
00334       if (this->ami_response_handler_allocator_ == 0)
00335         {
00336           this->ami_response_handler_allocator_ =
00337             this->resource_factory ()->ami_response_handler_allocator ();
00338         }
00339     }
00340 
00341   return this->ami_response_handler_allocator_;
00342 }
00343 
00344 int
00345 TAO_Thread_Lane_Resources::open_acceptor_registry (const TAO_EndpointSet &endpoint_set,
00346                                                    bool ignore_address
00347                                                    )
00348 {
00349   // Access the acceptor registry.
00350   TAO_Acceptor_Registry &ar = this->acceptor_registry ();
00351 
00352   // Open it.
00353   int result = ar.open (&this->orb_core_,
00354                         this->leader_follower ().reactor (),
00355                         endpoint_set,
00356                         ignore_address
00357                        );
00358 
00359   return result;
00360 }
00361 
00362 TAO_Resource_Factory *
00363 TAO_Thread_Lane_Resources::resource_factory (void)
00364 {
00365   return this->orb_core_.resource_factory ();
00366 }
00367 
00368 void
00369 TAO_Thread_Lane_Resources::finalize (void)
00370 {
00371   // Close connectors before acceptors!
00372   // Ask the registry to close all registered connectors.
00373   if (this->connector_registry_ != 0)
00374     {
00375       this->connector_registry_->close_all ();
00376       delete this->connector_registry_;
00377       this->connector_registry_ = 0;
00378     }
00379 
00380   // Ask the registry to close all registered acceptors.
00381   if (this->acceptor_registry_ != 0)
00382     {
00383       this->acceptor_registry_->close_all ();
00384       delete this->acceptor_registry_;
00385       this->acceptor_registry_ = 0;
00386     }
00387 
00388   // Set of handlers still in the connection cache.
00389   TAO::Connection_Handler_Set handlers;
00390 
00391   // Close the transport cache and return the handlers that were still
00392   // registered.  The cache will decrease the #REFCOUNT# on the
00393   // handler when it removes the handler from cache.  However,
00394   // #REFCOUNT# is increased when the handler is placed in the handler
00395   // set.
00396   this->transport_cache_->close (handlers);
00397 
00398   // Go through the handler set, closing the connections and removing
00399   // the references.
00400   TAO_Connection_Handler **handler = 0;
00401 
00402   for (TAO::Connection_Handler_Set::iterator iter (handlers);
00403        iter.next (handler);
00404        iter.advance ())
00405     {
00406       // Connection is closed.  Potential removal from the Reactor.
00407       (*handler)->close_connection ();
00408 
00409       // #REFCOUNT# related to the handler set decreases.
00410       (*handler)->transport ()->remove_reference ();
00411     }
00412 
00413   delete this->transport_cache_;
00414   this->transport_cache_ = 0;
00415 
00416   delete this->leader_follower_;
00417   this->leader_follower_ = 0;
00418 
00419   // Delete all the allocators here.. They shouldnt be done earlier,
00420   // lest some of the contents in the above, say reactor or acceptor
00421   // may use memory from the pool..
00422   if (this->input_cdr_dblock_allocator_ != 0)
00423     {
00424       this->input_cdr_dblock_allocator_->remove ();
00425       delete this->input_cdr_dblock_allocator_;
00426       this->input_cdr_dblock_allocator_ = 0;
00427     }
00428 
00429   if (this->input_cdr_buffer_allocator_ != 0)
00430     {
00431       this->input_cdr_buffer_allocator_->remove ();
00432       delete this->input_cdr_buffer_allocator_;
00433       this->input_cdr_buffer_allocator_ = 0;
00434     }
00435 
00436   if (this->input_cdr_msgblock_allocator_ != 0)
00437     {
00438       this->input_cdr_msgblock_allocator_->remove ();
00439       delete this->input_cdr_msgblock_allocator_;
00440       this->input_cdr_msgblock_allocator_ = 0;
00441     }
00442 
00443   if (this->transport_message_buffer_allocator_ != 0)
00444     {
00445       this->transport_message_buffer_allocator_->remove ();
00446       delete this->transport_message_buffer_allocator_;
00447       this->transport_message_buffer_allocator_ = 0;
00448     }
00449 
00450   if (this->output_cdr_dblock_allocator_ != 0)
00451     {
00452       this->output_cdr_dblock_allocator_->remove ();
00453       delete this->output_cdr_dblock_allocator_;
00454       this->output_cdr_dblock_allocator_ = 0;
00455     }
00456 
00457   if (this->output_cdr_buffer_allocator_ != 0)
00458     {
00459       this->output_cdr_buffer_allocator_->remove ();
00460       delete this->output_cdr_buffer_allocator_;
00461       this->output_cdr_buffer_allocator_ = 0;
00462     }
00463 
00464   if (this->output_cdr_msgblock_allocator_ != 0)
00465     {
00466       this->output_cdr_msgblock_allocator_->remove ();
00467       delete this->output_cdr_msgblock_allocator_;
00468       this->output_cdr_msgblock_allocator_ = 0;
00469     }
00470 
00471   if (this->amh_response_handler_allocator_ != 0)
00472     {
00473       this->amh_response_handler_allocator_->remove ();
00474       delete this->amh_response_handler_allocator_;
00475       this->amh_response_handler_allocator_ = 0;
00476     }
00477 
00478   if (this->ami_response_handler_allocator_ != 0)
00479     {
00480       this->ami_response_handler_allocator_->remove ();
00481       delete this->ami_response_handler_allocator_;
00482       this->ami_response_handler_allocator_ = 0;
00483     }
00484 }
00485 
00486 void
00487 TAO_Thread_Lane_Resources::shutdown_reactor (void)
00488 {
00489   TAO_Leader_Follower &leader_follower = this->leader_follower ();
00490 
00491   ACE_GUARD (TAO_SYNCH_MUTEX,
00492              ace_mon,
00493              leader_follower.lock ());
00494 
00495   ACE_Reactor *reactor = leader_follower.reactor ();
00496 
00497   // Wakeup all the threads waiting blocked in the event loop, this
00498   // does not guarantee that they will all go away, but reduces the
00499   // load on the POA....
00500 
00501   // If there are some client threads running we have to wait until
00502   // they finish, when the last one does it will shutdown the reactor
00503   // for us.  Meanwhile no new requests will be accepted because the
00504   // POA will not process them.
00505   if (!this->orb_core_.resource_factory ()->drop_replies_during_shutdown () &&
00506       leader_follower.has_clients ())
00507     {
00508       reactor->wakeup_all_threads ();
00509       return;
00510     }
00511 
00512   // End the reactor if we want shutdown dropping replies along the
00513   // way.
00514   reactor->end_reactor_event_loop ();
00515 }
00516 
00517 void
00518 TAO_Thread_Lane_Resources::cleanup_rw_transports (void)
00519 {
00520   // If we have no-drop-reply strategy or already fininalized simply return.
00521   if (!this->orb_core_.resource_factory ()->drop_replies_during_shutdown () ||
00522        this->transport_cache_ == 0)
00523     return;
00524 
00525   // Set of handlers still in the connection cache.
00526   TAO::Connection_Handler_Set handlers;
00527 
00528   this->transport_cache_->blockable_client_transports (handlers);
00529 
00530   // Go through the handler set, closing the connections and removing
00531   // the references.
00532   TAO_Connection_Handler **handler = 0;
00533 
00534   for (TAO::Connection_Handler_Set::iterator iter (handlers);
00535        iter.next (handler);
00536        iter.advance ())
00537     {
00538       // Connection is closed. There will be a double closure but that
00539       // is okay.
00540       (*handler)->release_os_resources ();
00541 
00542       // #REFCOUNT# related to the handler set decreases.
00543       (*handler)->transport ()->remove_reference ();
00544     }
00545 }
00546 
00547 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:07:37 2008 for TAO by doxygen 1.3.6