summaryrefslogtreecommitdiff
path: root/ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp')
-rw-r--r--ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp b/ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp
new file mode 100644
index 00000000000..b4d9df059ea
--- /dev/null
+++ b/ACE/TAO/orbsvcs/orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.cpp
@@ -0,0 +1,440 @@
+// $Id$
+
+#include "orbsvcs/Notify/MonitorControlExt/MonitorEventChannelFactory.h"
+#include "orbsvcs/Notify/MonitorControlExt/NotifyMonitoringExtC.h"
+#include "orbsvcs/Notify/MonitorControlExt/MonitorEventChannel.h"
+#include "orbsvcs/Notify/MonitorControl/Dynamic_Statistic.h"
+#include "orbsvcs/Notify/Properties.h"
+#include "orbsvcs/Notify/Builder.h"
+
+#include "ace/Monitor_Point_Registry.h"
+
+#if defined (TAO_HAS_MONITOR_FRAMEWORK) && (TAO_HAS_MONITOR_FRAMEWORK == 1)
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// ******************************************************************
+// Dynamic Statistic Classes
+// ******************************************************************
+
+class EventChannels
+ : public TAO_Dynamic_Statistic<TAO_MonitorEventChannelFactory>
+{
+public:
+ EventChannels (TAO_MonitorEventChannelFactory* ecf,
+ const ACE_CString& name,
+ Monitor_Control_Types::Information_Type type,
+ bool active)
+ : TAO_Dynamic_Statistic<TAO_MonitorEventChannelFactory> (ecf,
+ name.c_str (),
+ type),
+ active_ (active)
+ {
+ }
+
+ virtual void update (void)
+ {
+ if (this->type () == Monitor_Control_Types::MC_LIST)
+ {
+ Monitor_Control_Types::NameList names;
+ this->interf_->get_ecs (&names, this->active_);
+ this->receive (names);
+ }
+ else
+ {
+ this->receive (this->interf_->get_ecs (0, this->active_));
+ }
+ }
+
+private:
+ bool active_;
+};
+
+// ******************************************************************
+// TAO_MonitorEventChannelFactory Methods
+// ******************************************************************
+
+TAO_MonitorEventChannelFactory::TAO_MonitorEventChannelFactory (
+ const char* name)
+ : name_ (name)
+{
+ if (name != 0)
+ {
+ ACE_CString dir_name (this->name_ + "/");
+ ACE_CString stat_name (dir_name +
+ NotifyMonitoringExt::ActiveEventChannelCount);
+
+ EventChannels* event_channels = 0;
+ ACE_NEW (event_channels,
+ EventChannels (this,
+ stat_name,
+ Monitor_Control_Types::MC_NUMBER,
+ true));
+
+ event_channels->add_to_registry ();
+ event_channels->remove_ref ();
+
+ this->stat_names_.push_back (stat_name);
+
+ stat_name = dir_name + NotifyMonitoringExt::InactiveEventChannelCount;
+ event_channels = 0;
+ ACE_NEW (event_channels,
+ EventChannels (this,
+ stat_name,
+ Monitor_Control_Types::MC_NUMBER,
+ false));
+
+ event_channels->add_to_registry ();
+ event_channels->remove_ref ();
+
+ this->stat_names_.push_back (stat_name);
+
+ stat_name = dir_name + NotifyMonitoringExt::ActiveEventChannelNames;
+ event_channels = 0;
+ ACE_NEW (event_channels,
+ EventChannels (this,
+ stat_name,
+ Monitor_Control_Types::MC_LIST,
+ true));
+
+ event_channels->add_to_registry ();
+ event_channels->remove_ref ();
+
+ this->stat_names_.push_back (stat_name);
+
+ stat_name = dir_name + NotifyMonitoringExt::InactiveEventChannelNames;
+ event_channels = 0;
+ ACE_NEW (event_channels,
+ EventChannels (this,
+ stat_name,
+ Monitor_Control_Types::MC_LIST,
+ false));
+
+ event_channels->add_to_registry ();
+ event_channels->remove_ref ();
+
+ this->stat_names_.push_back (stat_name);
+
+ stat_name = dir_name + NotifyMonitoringExt::EventChannelCreationTime;
+ Monitor_Base* timestamp = 0;
+ ACE_NEW (timestamp,
+ Timestamp_Monitor (stat_name.c_str ()));
+
+ ACE_Time_Value tv (ACE_OS::gettimeofday());
+ timestamp->receive (tv.sec () + (tv.usec () / 1000000.0));
+
+ timestamp->add_to_registry ();
+ timestamp->remove_ref ();
+
+ this->stat_names_.push_back (stat_name);
+
+ Monitor_Point_Registry* instance =
+ Monitor_Point_Registry::instance ();
+
+ ACE_WRITE_GUARD (TAO_SYNCH_RW_MUTEX, guard, this->mutex_);
+
+ Monitor_Base* names =
+ instance->get (NotifyMonitoringExt::EventChannelFactoryNames);
+
+ if (names == 0)
+ {
+ stat_name = NotifyMonitoringExt::EventChannelFactoryNames;
+ ACE_NEW_THROW_EX (names,
+ Monitor_Base (stat_name.c_str (),
+ Monitor_Control_Types::MC_LIST),
+ CORBA::NO_MEMORY ());
+ names->add_to_registry ();
+ }
+
+ Monitor_Control_Types::NameList list = names->get_list ();
+ list.push_back (this->name_);
+ names->receive (list);
+ names->remove_ref ();
+ }
+}
+
+TAO_MonitorEventChannelFactory::~TAO_MonitorEventChannelFactory (void)
+{
+ Monitor_Point_Registry* instance = Monitor_Point_Registry::instance ();
+ size_t size = this->stat_names_.size ();
+
+ for (size_t i = 0; i < size; ++i)
+ {
+ instance->remove (this->stat_names_[i].c_str ());
+ }
+}
+
+CosNotifyChannelAdmin::EventChannel_ptr
+TAO_MonitorEventChannelFactory::create_named_channel (
+ const CosNotification::QoSProperties& initial_qos,
+ const CosNotification::AdminProperties& initial_admin,
+ CosNotifyChannelAdmin::ChannelID_out id,
+ const char* name)
+{
+ if (ACE_OS::strlen (name) == 0)
+ {
+ throw NotifyMonitoringExt::NameMapError ();
+ }
+
+ ACE_CString sname (this->name_ + "/");
+ sname += name;
+
+ ACE_WRITE_GUARD_RETURN (TAO_SYNCH_RW_MUTEX, guard, this->mutex_, 0);
+
+ // Make sure the name isn't already used.
+ if (this->map_.find (sname) == 0)
+ {
+ throw NotifyMonitoringExt::NameAlreadyUsed ();
+ }
+
+ CosNotifyChannelAdmin::EventChannel_var ec =
+ TAO_Notify_Properties::instance ()->builder ()->build_event_channel (
+ this,
+ initial_qos,
+ initial_admin,
+ id,
+ sname.c_str ());
+
+ if (CORBA::is_nil (ec.in ()))
+ {
+ return CosNotifyChannelAdmin::EventChannel::_nil ();
+ }
+
+ // Event channel creation was successful, try to bind it in our map.
+ if (this->map_.bind (sname, id) != 0)
+ {
+ throw NotifyMonitoringExt::NameMapError ();
+ }
+
+ // The destructor of this object will unbind the
+ // name from the map unless release is called.
+ Unbinder unbinder (this->map_, sname);
+
+ this->self_change ();
+
+ unbinder.release ();
+ return ec._retn ();
+}
+
+CosNotifyChannelAdmin::EventChannel_ptr
+TAO_MonitorEventChannelFactory::create_channel (
+ const CosNotification::QoSProperties& initial_qos,
+ const CosNotification::AdminProperties& initial_admin,
+ CosNotifyChannelAdmin::ChannelID_out id)
+{
+ CosNotifyChannelAdmin::EventChannel_var ec =
+ this->TAO_Notify_EventChannelFactory::create_channel (initial_qos,
+ initial_admin,
+ id);
+
+ if (CORBA::is_nil (ec.in ()))
+ {
+ return CosNotifyChannelAdmin::EventChannel::_nil ();
+ }
+
+ // Make sure we can get down to the real event channel
+ TAO_MonitorEventChannel* mec =
+ dynamic_cast<TAO_MonitorEventChannel*> (ec->_servant ());
+
+ if (mec == 0)
+ {
+ throw CORBA::INTERNAL ();
+ }
+
+ // Construct the name using the new id
+ ACE_CString sname (this->name_ + "/");
+ char name[64];
+ ACE_OS::sprintf(name, "%d", id);
+ sname += name;
+
+ ACE_WRITE_GUARD_RETURN (TAO_SYNCH_RW_MUTEX, guard, this->mutex_, 0);
+
+ // Make sure the name isn't already used.
+ if (this->map_.find (sname) == 0)
+ throw NotifyMonitoringExt::NameAlreadyUsed ();
+
+ // Event channel creation was successful, try to bind it in our map
+ if (this->map_.bind (sname, id) != 0)
+ {
+ throw NotifyMonitoringExt::NameMapError ();
+ }
+
+ // Set the name and statistics on the event channel.
+ mec->add_stats (sname.c_str ());
+
+ return ec._retn ();
+}
+
+void
+TAO_MonitorEventChannelFactory::remove (TAO_Notify_EventChannel* channel)
+{
+ TAO_MonitorEventChannel* mec =
+ dynamic_cast<TAO_MonitorEventChannel*> (channel);
+
+ if (mec != 0)
+ {
+ ACE_WRITE_GUARD (TAO_SYNCH_RW_MUTEX, guard, this->mutex_);
+ this->map_.unbind (mec->name ());
+ }
+
+ this->TAO_Notify_EventChannelFactory::remove (channel);
+}
+
+size_t
+TAO_MonitorEventChannelFactory::get_suppliers (
+ CosNotifyChannelAdmin::ChannelID id)
+{
+ size_t count = 0;
+ CosNotifyChannelAdmin::EventChannel_var ec =
+ this->get_event_channel (id);
+
+ if (!CORBA::is_nil (ec.in ()))
+ {
+ CosNotifyChannelAdmin::AdminIDSeq_var supadmin_ids =
+ ec->get_all_supplieradmins ();
+ CORBA::ULong length = supadmin_ids->length ();
+
+ for (CORBA::ULong j = 0; j < length; ++j)
+ {
+ CosNotifyChannelAdmin::SupplierAdmin_var admin =
+ ec->get_supplieradmin (supadmin_ids[j]);
+
+ if (!CORBA::is_nil (admin.in ()))
+ {
+ CosNotifyChannelAdmin::ProxyIDSeq_var proxys =
+ admin->push_consumers ();
+ count += proxys->length ();
+ }
+ }
+ }
+
+ return count;
+}
+
+size_t
+TAO_MonitorEventChannelFactory::get_consumers (
+ CosNotifyChannelAdmin::ChannelID id)
+{
+ size_t count = 0;
+ CosNotifyChannelAdmin::EventChannel_var ec =
+ this->get_event_channel (id);
+
+ if (!CORBA::is_nil (ec.in ()))
+ {
+ CosNotifyChannelAdmin::AdminIDSeq_var conadmin_ids =
+ ec->get_all_consumeradmins ();
+ CORBA::ULong length = conadmin_ids->length ();
+
+ for (CORBA::ULong j = 0; j < length; ++j)
+ {
+ CosNotifyChannelAdmin::ConsumerAdmin_var admin =
+ ec->get_consumeradmin (conadmin_ids[j]);
+
+ if (!CORBA::is_nil (admin.in ()))
+ {
+ CosNotifyChannelAdmin::ProxyIDSeq_var proxys =
+ admin->push_suppliers ();
+ count += proxys->length ();
+ }
+ }
+ }
+
+ return count;
+}
+
+size_t
+TAO_MonitorEventChannelFactory::get_ecs (
+ Monitor_Control_Types::NameList* names,
+ bool active)
+{
+ size_t count = 0;
+ CosNotifyChannelAdmin::ChannelIDSeq_var ids = this->get_all_channels ();
+
+ CORBA::ULong total = ids->length ();
+
+ for (CORBA::ULong i = 0; i < total; ++i)
+ {
+ CosNotifyChannelAdmin::ChannelID id = ids[i];
+ bool want_event_channel = !active;
+
+ // Check for connected consumers.
+ size_t consumers = this->get_consumers (id);
+
+ if (consumers > 0)
+ {
+ want_event_channel = active;
+ }
+
+ if ((!active && want_event_channel)
+ || (active && !want_event_channel))
+ {
+ // Check for connected suppliers
+ size_t suppliers = this->get_suppliers (id);
+
+ if (suppliers > 0)
+ {
+ want_event_channel = active;
+ }
+ }
+
+ if (want_event_channel)
+ {
+ count++;
+
+ if (names != 0)
+ {
+ ACE_READ_GUARD_RETURN (TAO_SYNCH_RW_MUTEX,
+ guard,
+ this->mutex_,
+ 0);
+
+ Map::iterator itr (this->map_);
+ Map::value_type* entry = 0;
+
+ while (itr.next (entry))
+ {
+ if (id == entry->item ())
+ {
+ names->push_back (entry->key ());
+ }
+
+ itr.advance ();
+ }
+ }
+ }
+ }
+
+ return count;
+}
+
+// ******************************************************************
+// Unbinder Helper
+// ******************************************************************
+
+TAO_MonitorEventChannelFactory::Unbinder::Unbinder (
+ TAO_MonitorEventChannelFactory::Map& map,
+ const ACE_CString& name)
+ : map_ (map),
+ name_ (name),
+ released_ (false)
+{
+}
+
+TAO_MonitorEventChannelFactory::Unbinder::~Unbinder (void)
+{
+ if (!this->released_)
+ {
+ this->map_.unbind (this->name_);
+ }
+}
+
+void
+TAO_MonitorEventChannelFactory::Unbinder::release (void)
+{
+ this->released_ = true;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_HAS_MONITOR_FRAMEWORK==1 */
+