diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp | 350 |
1 files changed, 332 insertions, 18 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp index 3985ef9d899..7606224d57f 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/EventChannel.cpp @@ -2,10 +2,6 @@ #include "EventChannel.h" -#if ! defined (__ACE_INLINE__) -#include "EventChannel.inl" -#endif /* __ACE_INLINE__ */ - #include "Container_T.h" #include "EventChannelFactory.h" #include "ConsumerAdmin.h" @@ -16,6 +12,15 @@ #include "Builder.h" #include "Find_Worker_T.h" #include "Seq_Worker_T.h" +#include "Topology_Saver.h" +#include "Save_Persist_Worker_T.h" +#include "Reconnect_Worker_T.h" + +#include "tao/debug.h" +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +# define DEBUG_LEVEL TAO_debug_level +#endif //DEBUG_LEVEL ACE_RCSID(Notify, TAO_Notify_EventChannel, "$Id$") @@ -54,7 +59,8 @@ TAO_Notify_EventChannel::init (TAO_Notify_EventChannelFactory* ecf , const CosNotification::AdminProperties & initial_admin ACE_ENV_ARG_DECL) { - this->TAO_Notify_Object::init (ecf); + // this-> on the following line confuses VC6 + initialize (ecf ACE_ENV_ARG_PARAMETER); this->ecf_ = ecf; @@ -109,16 +115,71 @@ TAO_Notify_EventChannel::init (TAO_Notify_EventChannelFactory* ecf this->set_admin (initial_admin ACE_ENV_ARG_PARAMETER); ACE_CHECK; - CosNotifyChannelAdmin::AdminID id; + // Note originally default admins were allocated here, bt this caused problems + // attempting to save the topology changes before the Event Channel was completely + // constructed and linked to the ECF. + // Lazy evaluation also avoids creating unneded admins. +} + + +void +TAO_Notify_EventChannel::init (TAO_Notify::Topology_Parent * parent + ACE_ENV_ARG_DECL) +{ + // this-> on the following line confuses VC6 + initialize (parent ACE_ENV_ARG_PARAMETER); + + this->ecf_ = dynamic_cast <TAO_Notify_EventChannelFactory*>(parent); + ACE_ASSERT (this->ecf_ != 0); + + this->ecf_->_incr_refcnt (); + + // Init ca_container_ + ACE_NEW_THROW_EX (this->ca_container_, + TAO_Notify_ConsumerAdmin_Container (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->ca_container_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; - // Set the default ConsumerAdmin. - this->default_consumer_admin_ = this->new_for_consumers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + // Init ca_container_ + ACE_NEW_THROW_EX (this->sa_container_, + TAO_Notify_SupplierAdmin_Container (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->sa_container_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify_AdminProperties* admin_properties = 0; + + // Set the admin properties. + ACE_NEW_THROW_EX (admin_properties, + TAO_Notify_AdminProperties (), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + this->admin_properties_ = admin_properties; + + // create the event manager. @@ use factory + ACE_NEW_THROW_EX (this->event_manager_, + TAO_Notify_Event_Manager (), + CORBA::INTERNAL ()); + ACE_CHECK; + + this->event_manager_->init (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + const CosNotification::QoSProperties &default_ec_qos = + TAO_Notify_PROPERTIES::instance ()->default_event_channel_qos_properties (); + + this->set_qos (default_ec_qos ACE_ENV_ARG_PARAMETER); ACE_CHECK; - // Set the default SupplierAdmin. - this->default_supplier_admin_ = this->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); } + void TAO_Notify_EventChannel::_add_ref (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { @@ -214,20 +275,63 @@ TAO_Notify_EventChannel::MyFactory (ACE_ENV_SINGLE_ARG_DECL) } CosNotifyChannelAdmin::ConsumerAdmin_ptr -TAO_Notify_EventChannel::default_consumer_admin (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::default_consumer_admin (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { + if (CORBA::is_nil (default_consumer_admin_.in ())) + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->default_admin_mutex_, CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + if (CORBA::is_nil (default_consumer_admin_.in ())) + { + CosNotifyChannelAdmin::AdminID id; + this->default_consumer_admin_ = this->new_for_consumers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + // Wish there was a better way to do this! + PortableServer::ServantBase * admin_servant = + this->poa_->reference_to_servant ( + this->default_consumer_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::ConsumerAdmin::_nil()); + TAO_Notify_Admin * pAdmin = dynamic_cast <TAO_Notify_Admin *> (admin_servant); + ACE_ASSERT (pAdmin != 0); // if this assert triggers, we have mixed implementations? + if (pAdmin != 0) + { + pAdmin->set_default (true); + } + } + } return CosNotifyChannelAdmin::ConsumerAdmin::_duplicate (this->default_consumer_admin_.in ()); } CosNotifyChannelAdmin::SupplierAdmin_ptr -TAO_Notify_EventChannel::default_supplier_admin (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::default_supplier_admin (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { + if (CORBA::is_nil (default_supplier_admin_.in ())) + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->default_admin_mutex_, CosNotifyChannelAdmin::SupplierAdmin::_nil()); + if (CORBA::is_nil (default_supplier_admin_.in ())) + { + CosNotifyChannelAdmin::AdminID id; + this->default_supplier_admin_ = this->new_for_suppliers (CosNotifyChannelAdmin::OR_OP, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CosNotifyChannelAdmin::SupplierAdmin::_nil()); + PortableServer::ServantBase * admin_servant = + this->poa_->poa()->reference_to_servant ( + this->default_supplier_admin_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + TAO_Notify_Admin * pAdmin = dynamic_cast <TAO_Notify_Admin *> (admin_servant); + ACE_ASSERT (pAdmin != 0); // if this assert triggers, we have mixed implementations? + if (pAdmin != 0) + { + pAdmin->set_default (true); + } + } + } return CosNotifyChannelAdmin::SupplierAdmin::_duplicate (this->default_supplier_admin_.in ()); } @@ -248,7 +352,12 @@ TAO_Notify_EventChannel::new_for_consumers (CosNotifyChannelAdmin::InterFilterGr )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_consumer_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ::CosNotifyChannelAdmin::ConsumerAdmin_var ca = + TAO_Notify_PROPERTIES::instance()->builder()->build_consumer_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (ca._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (ca._retn ()); + return ca._retn (); } ::CosNotifyChannelAdmin::SupplierAdmin_ptr @@ -260,7 +369,12 @@ TAO_Notify_EventChannel::new_for_suppliers (CosNotifyChannelAdmin::InterFilterGr CORBA::SystemException )) { - return TAO_Notify_PROPERTIES::instance()->builder()->build_supplier_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ::CosNotifyChannelAdmin::SupplierAdmin_var sa = + TAO_Notify_PROPERTIES::instance()->builder()->build_supplier_admin (this, op, id ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (sa._retn ()); + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (sa._retn ()); + return sa._retn (); } CosNotifyChannelAdmin::ConsumerAdmin_ptr @@ -337,21 +451,21 @@ TAO_Notify_EventChannel::get_admin (ACE_ENV_SINGLE_ARG_DECL) } CosEventChannelAdmin::ConsumerAdmin_ptr -TAO_Notify_EventChannel::for_consumers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::for_consumers (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { - return CosEventChannelAdmin::ConsumerAdmin::_duplicate (this->default_consumer_admin_.in ()); + return this->default_consumer_admin(ACE_ENV_SINGLE_ARG_PARAMETER); } CosEventChannelAdmin::SupplierAdmin_ptr -TAO_Notify_EventChannel::for_suppliers (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +TAO_Notify_EventChannel::for_suppliers (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { - return CosEventChannelAdmin::SupplierAdmin::_duplicate (this->default_supplier_admin_.in ()); + return this->default_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -367,6 +481,196 @@ TAO_Notify_EventChannel::validate_qos (const CosNotification::QoSProperties & /* ACE_THROW (CORBA::NO_IMPLEMENT ()); } +void +TAO_Notify_EventChannel::save_persistent (TAO_Notify::Topology_Saver& saver ACE_ENV_ARG_DECL) +{ + bool changed = this->self_changed_; + this->self_changed_ = false; + this->children_changed_ = false; + + if (is_persistent ()) + { + TAO_Notify::NVPList attrs; + this->save_attrs(attrs); + + bool want_all_children = saver.begin_object( + this->id(), "channel", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Save_Persist_Worker<TAO_Notify_ConsumerAdmin> ca_wrk(saver, want_all_children); + + ACE_ASSERT(this->ca_container_ != 0); + this->ca_container_->collection()->for_each(&ca_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Save_Persist_Worker<TAO_Notify_SupplierAdmin> sa_wrk(saver, want_all_children); + ACE_ASSERT(this->sa_container_ != 0); + this->sa_container_->collection()->for_each(&sa_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + saver.end_object(this->id(), "channel" ACE_ENV_ARG_PARAMETER); + } +} + +namespace { + template<class T> + void add_attr(TAO_Notify::NVPList& attrs, const T& prop) { + if (prop.is_valid()) + { + attrs.push_back(TAO_Notify::NVP (prop)); + } + } +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template void add_attr<TAO_Notify_Property_Boolean>(TAO_Notify::NVPList&, + const TAO_Notify_Property_Boolean&); +template void add_attr<TAO_Notify_Property_T<int> >(TAO_Notify::NVPList&, + const TAO_Notify_Property_T<int>&); +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate void add_attr<TAO_Notify_Property_Boolean>(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_Boolean&) +#pragma instantiate void add_attr<TAO_Notify_Property_T<int> >(\ + TAO_Notify::NVPList&, const TAO_Notify_Property_T<int>&) +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ +} + +void +TAO_Notify_EventChannel::save_attrs(TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::save_attrs(attrs); + add_attr(attrs, this->admin_properties_->max_global_queue_length()); + add_attr(attrs, this->admin_properties_->max_consumers()); + add_attr(attrs, this->admin_properties_->max_suppliers()); + add_attr(attrs, this->admin_properties_->reject_new_events()); +} + +void +TAO_Notify_EventChannel::load_attrs(const TAO_Notify::NVPList& attrs) +{ + TAO_Notify_Object::load_attrs(attrs); + attrs.load(this->admin_properties_->max_global_queue_length()); + attrs.load(this->admin_properties_->max_consumers()); + attrs.load(this->admin_properties_->max_suppliers()); + attrs.load(this->admin_properties_->reject_new_events()); + this->admin_properties_->init(); +} + +TAO_Notify::Topology_Object * +TAO_Notify_EventChannel::load_child (const ACE_CString &type, + CORBA::Long id, + const TAO_Notify::NVPList& attrs + ACE_ENV_ARG_DECL) +{ + TAO_Notify::Topology_Object* result = this; + if (type == "consumer_admin") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) EventChannel reload consumer_admin %d\n") + , static_cast<int> (id) + )); + + // call special builder method to reload + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + TAO_Notify_ConsumerAdmin * ca = bld->build_consumer_admin ( + this, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + ca->load_attrs (attrs); + if (ca->is_default ()) + { + CORBA::Object_var caob = this->poa_->servant_to_reference (ca ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + this->default_consumer_admin_ = + CosNotifyChannelAdmin::ConsumerAdmin::_narrow ( + caob.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + result = ca; + } + else if (type == "supplier_admin") + { + if (DEBUG_LEVEL) ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) EventChannel reload supplier_admin %d\n") + , static_cast<int> (id) + )); + TAO_Notify_Builder* bld = TAO_Notify_PROPERTIES::instance()->builder(); + + TAO_Notify_SupplierAdmin * sa = bld->build_supplier_admin ( + this, + id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + sa->load_attrs (attrs); + if (sa->is_default ()) + { + CORBA::Object_var saob = this->poa_->servant_to_reference (sa ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + this->default_supplier_admin_ = + CosNotifyChannelAdmin::SupplierAdmin::_narrow ( + saob.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + result = sa; + } + return result; +} +TAO_Notify_ProxyConsumer * +TAO_Notify_EventChannel::find_proxy_consumer (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxyConsumer * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_SupplierAdmin_Find_Worker find_worker; + TAO_Notify_SupplierAdmin * admin = find_worker.find (id_path[position], *this->sa_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (admin != 0) + { + result = admin->find_proxy_consumer (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + +TAO_Notify_ProxySupplier * +TAO_Notify_EventChannel::find_proxy_supplier (TAO_Notify::IdVec & id_path, size_t position ACE_ENV_ARG_DECL) +{ + TAO_Notify_ProxySupplier * result = 0; + size_t path_size = id_path.size (); + if (position < path_size) + { + TAO_Notify_ConsumerAdmin_Find_Worker find_worker; + TAO_Notify_ConsumerAdmin * admin = find_worker.find (id_path[position], *this->ca_container_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + ++position; + if (admin != 0) + { + result = admin->find_proxy_supplier (id_path, position + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(0); + } + } + return result; +} + + +void +TAO_Notify_EventChannel::reconnect (ACE_ENV_SINGLE_ARG_DECL) +{ + TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin> ca_wrk; + ACE_ASSERT(this->ca_container_ != 0); + this->ca_container_->collection()->for_each(&ca_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin> sa_wrk; + ACE_ASSERT(this->sa_container_ != 0); + this->sa_container_->collection()->for_each(&sa_wrk ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_Notify_Find_Worker_T<TAO_Notify_ConsumerAdmin @@ -387,6 +691,11 @@ template class TAO_Notify_Container_T <TAO_Notify_SupplierAdmin>; template class TAO_ESF_Shutdown_Proxy<TAO_Notify_ConsumerAdmin>; template class TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin>; +template class TAO_Notify::Save_Persist_Worker<TAO_Notify_ConsumerAdmin>; +template class TAO_Notify::Save_Persist_Worker<TAO_Notify_SupplierAdmin>; +template class TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin>; +template class TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin>; + #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate TAO_Notify_Find_Worker_T<TAO_Notify_ConsumerAdmin @@ -407,4 +716,9 @@ template class TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin>; #pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_Notify_ConsumerAdmin> #pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_Notify_SupplierAdmin> +#pragma instantiate Save_Persist_Worker<TAO_Notify_ConsumerAdmin> +#pragma instantiate Save_Persist_Worker<TAO_Notify_SupplierAdmin> +#pragma instantiate TAO_Notify::Reconnect_Worker<TAO_Notify_ConsumerAdmin> +#pragma instantiate TAO_Notify::Reconnect_Worker<TAO_Notify_SupplierAdmin> + #endif /*ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |