Logo Search packages:      
Sourcecode: tango version File versions  Download package

eventsupplier.h

////////////////////////////////////////////////////////////////////////////////
///
///  file       eventsupplier.h
///
///           C++ include file for implementing the TANGO event server and 
///         client singleton classes - EventSupplier and EventConsumer.
///             These classes are used to send events from the server
///             to the notification service and to receive events from
///             the notification service.
///
///         author(s) : A.Gotz (goetz@esrf.fr)
///
///         original : 7 April 2003
//
// Copyright (C) :      2003,2004,2005,2006,2007,2008,2009,2010,2011
//                                  European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Tango is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Tango.  If not, see <http://www.gnu.org/licenses/>.
///
///         $Revision: 16143 $
///
///         copyright : European Synchrotron Radiation Facility
///                         BP 220, Grenoble 38043
///                         FRANCE
///
////////////////////////////////////////////////////////////////////////////////

#ifndef _EVENT_SUPPLIER_API_H
#define _EVENT_SUPPLIER_API_H

#include <except.h>

#if defined (_TG_WINDOWS_) && defined (_USRDLL) && !defined(_TANGO_LIB)
#define USE_stub_in_nt_dll
#endif

#include <COS/CosNotification.hh>
#include <COS/CosNotifyChannelAdmin.hh>
#include <COS/CosNotifyComm.hh>

#if defined (_TG_WINDOWS_) && defined (_USRDLL) && !defined(_TANGO_LIB)
#undef USE_stub_in_nt_dll
#endif


#include <omnithread.h>
#ifndef _TG_WINDOWS_
#include <sys/time.h>
#endif
#include <math.h>


namespace Tango
{

00071 typedef struct _NotifService
{
      CosNotifyChannelAdmin::SupplierAdmin_var                    SupAdm;
      CosNotifyChannelAdmin::ProxyID                                          pID;
      CosNotifyChannelAdmin::ProxyConsumer_var                    ProCon; 
      CosNotifyChannelAdmin::StructuredProxyPushConsumer_var      StrProPush; 
      CosNotifyChannelAdmin::EventChannelFactory_var              EveChaFac;
      CosNotifyChannelAdmin::EventChannel_var                     EveCha;
      string                                                                              ec_ior;
} NotifService;


00083 class EventSupplier : public POA_CosNotifyComm::StructuredPushSupplier
{
public :

      TANGO_IMP_EXP static EventSupplier *create(CORBA::ORB_var,string,Database*,string &,Util *);
      void connect();
      void disconnect_structured_push_supplier();
      void disconnect_from_notifd();
      void subscription_change(const CosNotification::EventTypeSeq& added,const CosNotification::EventTypeSeq& deled);

      void push_heartbeat_event();
      string &get_event_channel_ior() {return event_channel_ior;}
      void set_svr_port_num(string &);

protected :

      EventSupplier(CORBA::ORB_var,
            CosNotifyChannelAdmin::SupplierAdmin_var,
            CosNotifyChannelAdmin::ProxyID, 
            CosNotifyChannelAdmin::ProxyConsumer_var, 
            CosNotifyChannelAdmin::StructuredProxyPushConsumer_var, 
            CosNotifyChannelAdmin::EventChannelFactory_var,
            CosNotifyChannelAdmin::EventChannel_var,
            string &);
            
private :
      static EventSupplier                                                    *_instance;
      CosNotifyChannelAdmin::EventChannel_var                     eventChannel;
      CosNotifyChannelAdmin::SupplierAdmin_var                    supplierAdmin;
      CosNotifyChannelAdmin::ProxyID                                          proxyId;
      CosNotifyChannelAdmin::ProxyConsumer_var                    proxyConsumer;
      CosNotifyChannelAdmin::StructuredProxyPushConsumer_var      structuredProxyPushConsumer;
      CosNotifyChannelAdmin::EventChannelFactory_var              eventChannelFactory;
      CORBA::ORB_var                                                                orb_;
      
      inline int timeval_diff(TimeVal before, TimeVal after)
      {
            return ((after.tv_sec-before.tv_sec)*1000000 + after.tv_usec - before.tv_usec);
      }
      int         heartbeat_period;
      int         subscription_timeout;
      string            event_channel_ior;
      string            fqdn_prefix;

      void get_attribute_value(AttributeValue attr_value, LastAttrValue &curr_attr_value);
      void reconnect_notifd();
      TANGO_IMP_EXP static void connect_to_notifd(NotifService &,CORBA::ORB_var &,string &,Database *,string &,Util *);
                  
      // Added a mutex to synchronize the access to 
      //    detect_and_push_change_event_3      and
      // detect_and_push_archive_event_3 which are used
      // from different threads
      omni_mutex        event_mutex;
      
      // Added a mutex to synchronize the access to 
      //    push_event_3 which is used
      // from different threads
      omni_mutex        push_mutex;
      
      // Added a mutex to synchronize the access to 
      //    detect_event_3 which is used
      // from different threads
      omni_mutex        detect_mutex;
      
public :
      void push_att_data_ready_event(DeviceImpl *,const string &,long,DevLong);
      void detect_and_push_events_3(DeviceImpl *,long,AttributeValue_3 *,AttributeValue_4 *,DevFailed *,string &,struct timeval *);


/////////////////////////////////////////////////////////////////////////////
//
//                WARNING
//                -------
//
////////////////////////////////////////////////////////////////////////////

// Unfortunately, with Suse 9.3 with gcc 3.3.4 and binutils 2.15.94,
// it was not possible to generate the shared libs of Tango
// (linker error messages).
// To solve this problem, it was necessary to duplicate these methods
// instead of simply using a template method. This generates a code
// duplicate but...... (all methods finishing with xxxx_3)
//
// Test with gcc 3.4.5 with binutils 2.16.1 did not solve the problems
// We need to check with gcc 4.x.x if we could remove this code duplicate
// The other methods are in eventsupplier.cpp
//
//
//--------------------------------------------------------------------------

                            
      template <typename T>
      void detect_and_push_events(DeviceImpl *device_impl,
                            long idl_vers,
                            T &attr_value,
                            DevFailed *except,
                            string &attr_name)
      {
            string event, domain_name;
            time_t now, change_subscription, periodic_subscription, archive_subscription;

            cout3 << "EventSupplier::detect_and_push_events(): called for attribute " << attr_name << endl;

            Attribute &attr = device_impl->dev_attr->get_attr_by_name(attr_name.c_str());

            now = time(NULL);
            change_subscription = now - attr.ext->event_change_subscription;
            periodic_subscription = now - attr.ext->event_periodic_subscription;
            archive_subscription = now - attr.ext->event_archive_subscription;

            cout3 << "EventSupplier::detect_and_push_events(): last subscription for change " << change_subscription << " periodic " << periodic_subscription << " archive " << archive_subscription << endl;
            if (change_subscription < EVENT_RESUBSCRIBE_PERIOD)
            {
                  detect_and_push_change_event(device_impl,attr_value,attr,attr_name,except);
            }
            if (periodic_subscription < EVENT_RESUBSCRIBE_PERIOD)
            {
                  detect_and_push_periodic_event(device_impl,attr_value,attr,attr_name,except);
            }
            if (archive_subscription < EVENT_RESUBSCRIBE_PERIOD)
            {
                  detect_and_push_archive_event(device_impl,attr_value,attr,attr_name,except);
            }
      }
      
      
      template <typename T>
      void push_att_conf_events(DeviceImpl *device_impl,
                            T &attr_conf,
                            DevFailed *except,
                            string &attr_name)
      {
            string event, domain_name;
            time_t now, att_conf_subscription;

            cout3 << "EventSupplier::push_att_conf_events(): called for attribute " << attr_name << endl;

            Attribute &attr = device_impl->dev_attr->get_attr_by_name(attr_name.c_str());

            now = time(NULL);
            att_conf_subscription = now - attr.ext->event_attr_conf_subscription;

            cout3 << "EventSupplier::push_att_conf_events(): last subscription " << att_conf_subscription << endl;
            
            vector<string> filterable_names;
            vector<double> filterable_data;
            vector<string> filterable_names_lg;
            vector<long> filterable_data_lg;
            
            string ev_type(CONF_TYPE_EVENT);

            push_event(device_impl,
                     ev_type,
                     filterable_names,
                     filterable_data,
                     filterable_names_lg,
                     filterable_data_lg,
                   attr_conf,
                     attr_name,
                     except);
      }


//+----------------------------------------------------------------------------
//
// method :             EventSupplier::detect_change()
// 
// description :  Method to detect if there is a change according to the
//                criterions and return a boolean set to true if a change
//                is detected
//
// argument : in :      attr : The attribute object
//                curr_attr_value : The current attribute value
//                archive : 
//                delta_change_rel :
//                delta_change_abs :
//                except : The exception thrown during the last
//                       attribute reading. NULL if no exception
//                force_change : A flag set to true if the change
//                             is due to a non mathematical reason
//                             (array size change, from exception to
//                            classic...)
//                dev : Pointer to the device
//
//-----------------------------------------------------------------------------


      bool detect_change_3(Attribute &attr,
                          AttributeValue_3 *curr_attr_value,
                          AttributeValue_4 *curr_attr_value_4,
                          bool archive,
                          double &delta_change_rel,
                          double &delta_change_abs,
                          DevFailed *except,
                          bool &force_change,
                          DeviceImpl *dev);
                          
                          
      template <typename T>
      bool detect_change(Attribute &attr,
                          T &curr_attr_value,
                          bool archive,
                          double &delta_change_rel,
                          double &delta_change_abs,
                          DevFailed *except,
                          bool &force_change,
                          DeviceImpl *dev)
      {
            bool is_change = false;
            
            cout3 << "EventSupplier::detect_change(): called for attribute " << attr.get_name() << endl;
            
            // get the mutex to synchronize the sending of events
            omni_mutex_lock l(detect_mutex);
            
//
// Send event, if the read_attribute failed or if it is the first time
// that the read_attribute succeed after a failure.
// Same thing if the attribute quality factor changes to INVALID
//
      
            if (except != NULL)
            {
                  force_change = true;
                  return true;
            }

            if (curr_attr_value.quality == Tango::ATTR_INVALID)
            {
                  force_change = true;
                  return true;
            }

            if (archive == true)
            {
                  if ((except == NULL) && (attr.ext->prev_archive_event.err == true))
                  {
                        force_change = true;
                        return true;
                  }

                  if ((curr_attr_value.quality != Tango::ATTR_INVALID) && (attr.ext->prev_archive_event.quality == Tango::ATTR_INVALID))
                  {
                        force_change = true;
                        return true;
                  }
            }
            else
            {           
                  if ((except == NULL) && (attr.ext->prev_change_event.err == true))
                  {
                        force_change = true;
                        return true;
                  }

                  if ((curr_attr_value.quality != Tango::ATTR_INVALID) && (attr.ext->prev_change_event.quality == Tango::ATTR_INVALID))
                  {
                        force_change = true;
                        return true;
                  }
            }

            const DevVarLong64Array *curr_seq_64, *prev_seq_64;   
            const DevVarLongArray *curr_seq_lo, *prev_seq_lo;
            const DevVarShortArray *curr_seq_sh, *prev_seq_sh;
            const DevVarDoubleArray *curr_seq_db, *prev_seq_db;
            const DevVarStringArray *curr_seq_str, *prev_seq_str;
            const DevVarFloatArray *curr_seq_fl, *prev_seq_fl;
            const DevVarBooleanArray *curr_seq_bo, *prev_seq_bo;
            const DevVarUShortArray *curr_seq_ush, *prev_seq_ush;
            const DevVarCharArray *curr_seq_uch, *prev_seq_uch;
            const DevVarULongArray *curr_seq_ulo, *prev_seq_ulo;
            const DevVarULong64Array *curr_seq_u64, *prev_seq_u64;
            const DevVarStateArray *curr_seq_state, *prev_seq_state;          
            
            double rel_change[2], abs_change[2];
            unsigned int i;
            unsigned int curr_seq_nb,prev_seq_nb;
            bool inited;

            CORBA::TypeCode_var ty = curr_attr_value.value.type();
            delta_change_rel = delta_change_abs = 0;

            bool enable_check = false;
            
            TangoMonitor &mon1 = dev->get_att_conf_monitor();
            mon1.get_monitor();
            if (!archive)
            {
                  rel_change[0] = attr.ext->rel_change[0];
                  rel_change[1] = attr.ext->rel_change[1];
                  abs_change[0] = attr.ext->abs_change[0];
                  abs_change[1] = attr.ext->abs_change[1];
                  inited = attr.ext->prev_change_event.inited;
                  if ((attr.ext->prev_change_event.quality != Tango::ATTR_INVALID) && (curr_attr_value.quality != Tango::ATTR_INVALID))
                            enable_check = true;
            }
            else
            {
                  rel_change[0] = attr.ext->archive_rel_change[0];
                  rel_change[1] = attr.ext->archive_rel_change[1];
                  abs_change[0] = attr.ext->archive_abs_change[0];
                  abs_change[1] = attr.ext->archive_abs_change[1];
                  inited = attr.ext->prev_archive_event.inited;
                  if ((attr.ext->prev_archive_event.quality != Tango::ATTR_INVALID) && (curr_attr_value.quality != Tango::ATTR_INVALID))
                            enable_check = true;            
            }
            mon1.rel_monitor();

            if (inited)
            {     
                  if (enable_check == true)
                  {
                        CORBA::TypeCode_var ty_alias = ty->content_type();
                        CORBA::TypeCode_var ty_seq = ty_alias->content_type();                              
                        switch (ty_seq->kind())
                        {
                        case CORBA::tk_long:          
                              curr_attr_value.value >>= curr_seq_lo;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_lo;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_lo;
                              curr_seq_nb = curr_seq_lo->length();
                              prev_seq_nb = prev_seq_lo->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_lo->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_lo)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_lo)[i] - (*prev_seq_lo)[i])*100/(*prev_seq_lo)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_lo)[i] == (*prev_seq_lo)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_lo)[i] - (*prev_seq_lo)[i];
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;

                        case CORBA::tk_longlong:
                              curr_attr_value.value >>= curr_seq_64;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_64;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_64;
                              curr_seq_nb = curr_seq_64->length();
                              prev_seq_nb = prev_seq_64->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_64->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_64)[i] != 0)
                                          {
                                                delta_change_rel = (double)(((*curr_seq_64)[i] - (*prev_seq_64)[i])*100/(*prev_seq_64)[i]);
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_64)[i] == (*prev_seq_64)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (double)((*curr_seq_64)[i] - (*prev_seq_64)[i]);
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;
                              
                        case CORBA::tk_short:
                              curr_attr_value.value >>= curr_seq_sh;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_sh;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_sh;
                              curr_seq_nb = curr_seq_sh->length();
                              prev_seq_nb = prev_seq_sh->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_sh->length(); i++)
                              {     
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_sh)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_sh)[i] - (*prev_seq_sh)[i])*100/(*prev_seq_sh)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_sh)[i] == (*prev_seq_sh)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_sh)[i] - (*prev_seq_sh)[i];
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;

                        case CORBA::tk_double:
                              curr_attr_value.value >>= curr_seq_db;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_db;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_db;
                              curr_seq_nb = curr_seq_db->length();
                              prev_seq_nb = prev_seq_db->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_db->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_db)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_db)[i] - (*prev_seq_db)[i])*100/(*prev_seq_db)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_db)[i] == (*prev_seq_db)[i]) delta_change_rel = 0;
                                          }
                                          
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_db)[i] - (*prev_seq_db)[i];
                                          
                                          // Correct for rounding errors !
                                          double max_change = delta_change_abs + (abs_change[1] * 1e-10);
                                          double min_change = delta_change_abs + (abs_change[0] * 1e-10);

                                          //if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          if (min_change <= abs_change[0] || max_change >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;

                        case CORBA::tk_string:
                              curr_attr_value.value >>= curr_seq_str;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_str;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_str;
                              curr_seq_nb = curr_seq_str->length();
                              prev_seq_nb = prev_seq_str->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_str->length(); i++)
                              {
                                    if (strcmp((*curr_seq_str)[i],(*prev_seq_str)[i]) != 0)
                                    {
                                          delta_change_rel = delta_change_abs = 100.;
                                          is_change = true;
                                          return(is_change);
                                    }
                              }
                              break;

                        case CORBA::tk_float:
                              curr_attr_value.value >>= curr_seq_fl;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_fl;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_fl;
                              curr_seq_nb = curr_seq_fl->length();
                              prev_seq_nb = prev_seq_fl->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_fl->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_fl)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_fl)[i] - (*prev_seq_fl)[i])*100/(*prev_seq_fl)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_fl)[i] == (*prev_seq_fl)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_fl)[i] - (*prev_seq_fl)[i];
                                          
                                          // Correct for rounding errors !
                                          double max_change = delta_change_abs + (abs_change[1] * 1e-10);
                                          double min_change = delta_change_abs + (abs_change[0] * 1e-10);
                                                                                          
                                          //if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          if (min_change <= abs_change[0] || max_change >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;

                        case CORBA::tk_ushort:
                              curr_attr_value.value >>= curr_seq_ush;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_ush;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_ush;
                              curr_seq_nb = curr_seq_ush->length();
                              prev_seq_nb = prev_seq_ush->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_ush->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_ush)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_ush)[i] - (*prev_seq_ush)[i])*100/(*prev_seq_ush)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_ush)[i] == (*prev_seq_ush)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_ush)[i] - (*prev_seq_ush)[i];
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;

                        case CORBA::tk_boolean:
                              curr_attr_value.value >>= curr_seq_bo;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_bo;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_bo;
                              curr_seq_nb = curr_seq_bo->length();
                              prev_seq_nb = prev_seq_bo->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_bo->length(); i++)
                              {
                                    if ((*curr_seq_bo)[i] != (*prev_seq_bo)[i])
                                    {
                                          delta_change_rel = delta_change_abs = 100.;
                                          is_change = true;
                                          return(is_change);
                                    }
                              }
                              break;

                        case CORBA::tk_octet:
                              curr_attr_value.value >>= curr_seq_uch;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_uch;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_uch;
                              curr_seq_nb = curr_seq_uch->length();
                              prev_seq_nb = prev_seq_uch->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_uch->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_uch)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_uch)[i] - (*prev_seq_uch)[i])*100/(*prev_seq_uch)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_uch)[i] == (*prev_seq_uch)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_uch)[i] - (*prev_seq_uch)[i];
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;
                              
                        case CORBA::tk_ulong:         
                              curr_attr_value.value >>= curr_seq_ulo;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_ulo;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_ulo;
                              curr_seq_nb = curr_seq_ulo->length();
                              prev_seq_nb = prev_seq_ulo->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_ulo->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_ulo)[i] != 0)
                                          {
                                                delta_change_rel = ((*curr_seq_ulo)[i] - (*prev_seq_ulo)[i])*100/(*prev_seq_ulo)[i];
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_ulo)[i] == (*prev_seq_ulo)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (*curr_seq_ulo)[i] - (*prev_seq_ulo)[i];
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;
                              
                        case CORBA::tk_ulonglong:
                              curr_attr_value.value >>= curr_seq_u64;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_u64;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_u64;
                              curr_seq_nb = curr_seq_u64->length();
                              prev_seq_nb = prev_seq_u64->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_u64->length(); i++)
                              {
                                    if (rel_change[0] != INT_MAX)
                                    {
                                          if ((*prev_seq_u64)[i] != 0)
                                          {
                                                delta_change_rel = (double)(((*curr_seq_u64)[i] - (*prev_seq_u64)[i])*100/(*prev_seq_u64)[i]);
                                          }
                                          else
                                          {
                                                delta_change_rel = 100;
                                                if ((*curr_seq_u64)[i] == (*prev_seq_u64)[i]) delta_change_rel = 0;
                                          }
                                          if (delta_change_rel <= rel_change[0] || delta_change_rel >= rel_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                                    if (abs_change[0] != INT_MAX)
                                    {
                                          delta_change_abs = (double)((*curr_seq_u64)[i] - (*prev_seq_u64)[i]);
                                          if (delta_change_abs <= abs_change[0] || delta_change_abs >= abs_change[1])
                                          {
                                                is_change = true;
                                                return(is_change);
                                          }
                                    }
                              }
                              break;
                              
                        case CORBA::tk_enum:
                              curr_attr_value.value >>= curr_seq_state;
                              if (archive == true)
                                    attr.ext->prev_archive_event.value >>= prev_seq_state;
                              else
                                    attr.ext->prev_change_event.value >>= prev_seq_state;
                              curr_seq_nb = curr_seq_state->length();
                              prev_seq_nb = prev_seq_state->length();
                              if (curr_seq_nb != prev_seq_nb)
                              {
                                    force_change = true;
                                    return true;
                              }
                              for (i=0; i<curr_seq_state->length(); i++)
                              {
                                    if ((*curr_seq_state)[i] != (*prev_seq_state)[i])
                                    {
                                          delta_change_rel = delta_change_abs = 100.;
                                          is_change = true;
                                          return(is_change);
                                    }
                              }
                              break;
                              
                        default:
                              break;
                        }
                  }
            }     

            cout3 << "EventSupplier::detect_change(): leaving for attribute " << attr.get_name() << endl;
            return(is_change);
      }


      void detect_and_push_change_event_3(DeviceImpl *device_impl,
                                     AttributeValue_3 *attr_value,
                                     AttributeValue_4 *attr_value_4,
                                     Attribute &attr,
                                     string &attr_name,
                                     DevFailed *except);
      
      template <typename T>
      void detect_and_push_change_event(DeviceImpl *device_impl,
                                     T &attr_value,
                                     Attribute &attr,
                                     string &attr_name,
                                     DevFailed *except)
      {
            string event, domain_name;
            double delta_change_rel = 0.0;
            double delta_change_abs = 0.0;
            bool is_change      = false;
            bool force_change   = false;
            bool quality_change = false;

            cout3 << "EventSupplier::detect_and_push_change_event(): called for attribute " << attr_name << endl;

            // get the mutex to synchronize the sending of events
            omni_mutex_lock l(event_mutex);

//
// if no attribute of this name is registered with change then
// insert the current value
//

            if (!attr.ext->prev_change_event.inited)
            {
                  if (except != NULL)
                        attr.ext->prev_change_event.err = true;
                  else
                  {
                        attr.ext->prev_change_event.value = attr_value.value;
                        attr.ext->prev_change_event.quality = attr_value.quality;
                        attr.ext->prev_change_event.err = false;
                  }
                  attr.ext->prev_change_event.inited = true;
            }
            else
            {
      
//
// determine delta_change in percent compared with previous event sent
// 
                  is_change = detect_change(attr,attr_value,false,delta_change_rel,delta_change_abs,except,force_change,device_impl);
                  cout3 << "EventSupplier::detect_and_push_change_event(): rel_change " << delta_change_rel << " abs_change " << delta_change_abs << " is change = " << is_change << endl;
            }
            
            // check whether the data quality has changed.
            // Fire event on a quality change.
            
            if ( attr.ext->prev_change_event.quality != attr_value.quality )
                  {
                  is_change = true;
                  quality_change = true;
                  }
            
      
            if (is_change)
            {
                  vector<string> filterable_names;
                  vector<double> filterable_data;
                  vector<string> filterable_names_lg;
                  vector<long> filterable_data_lg;

                  if (except != NULL)
                        attr.ext->prev_change_event.err = true;
                  else
                  {
                        attr.ext->prev_change_event.value = attr_value.value;
                        attr.ext->prev_change_event.quality = attr_value.quality;
                        attr.ext->prev_change_event.err = false;
                  }

                  domain_name = device_impl->get_name() + "/" + attr_name;
                  filterable_names.push_back("delta_change_rel");
                  filterable_data.push_back(delta_change_rel);
                  filterable_names.push_back("delta_change_abs");
                  filterable_data.push_back(delta_change_abs);
                  
                  filterable_names.push_back("forced_event");
                  if (force_change == true)
                        filterable_data.push_back((double)1.0);
                  else
                        filterable_data.push_back((double)0.0);
                  
                  filterable_names.push_back("quality");
                  if (quality_change == true)
                        filterable_data.push_back((double)1.0);
                  else
                        filterable_data.push_back((double)0.0);                     
                  
                  push_event(device_impl,
                           "change",
                           filterable_names,
                           filterable_data,
                           filterable_names_lg,
                           filterable_data_lg,
                           attr_value,
                           attr_name,
                           except);
            }
      cout3 << "EventSupplier::detect_and_push_change_event(): leaving for attribute " << attr_name << endl;            
      }

//+----------------------------------------------------------------------------
//
// method :             EventSupplier::detect_and_push_archive_event()
// 
// description :  Method to detect if there it is necessary
//                to push an archive event
//
// argument : in :      device_impl : The device
//                attr_value : The attribute value
//                attr_value_4 : The attribute value for devic eimplementing IDL 4
//                attr : The attribute object
//                attr_name : The attribute name
//                except : The exception thrown during the last
//                       attribute reading. NULL if no exception
//
//-----------------------------------------------------------------------------

      void detect_and_push_archive_event_3(DeviceImpl *device_impl,
                                      AttributeValue_3 *attr_value,
                                      AttributeValue_4 *attr_value_4, 
                                      Attribute &attr,
                                      string &attr_name,
                                      DevFailed *except,
                                      struct timeval *);
                                      
      template <typename T>
      void detect_and_push_archive_event(DeviceImpl *device_impl,
                                      T &attr_value, 
                                      Attribute &attr,
                                      string &attr_name,
                                      DevFailed *except)
      {
            string event, domain_name;
            double delta_change_rel = 0.0;
            double delta_change_abs = 0.0;
            bool is_change = false;
            bool force_change = false;
            bool period_change = false;
            bool value_change = false;

            cout3 << "EventSupplier::detect_and_push_archive_event(): called for attribute " << attr_name << endl;

            double now_ms, ms_since_last_periodic;
#ifdef _TG_WINDOWS_
            struct _timeb           now_win;
#endif
            struct timeval          now_timeval;

#ifdef _TG_WINDOWS_
            _ftime(&now_win);
            now_timeval.tv_sec = (unsigned long)now_win.time;
            now_timeval.tv_usec = (long)now_win.millitm * 1000;
#else
            gettimeofday(&now_timeval,NULL);
#endif

            // get the mutex to synchronize the sending of events
            omni_mutex_lock l(event_mutex);
            
            now_ms = (double)now_timeval.tv_sec * 1000. + (double)now_timeval.tv_usec / 1000.;
            ms_since_last_periodic = now_ms - attr.ext->archive_last_periodic;

            int arch_period;
            TangoMonitor &mon1 = device_impl->get_att_conf_monitor();
            mon1.get_monitor();
            arch_period = attr.ext->archive_period;
            mon1.rel_monitor();

            // Specify the precision interval for the archive period testing
            // 2% are used for periods < 5000 ms and
            // 100ms are used for periods > 5000 ms.
      
            if ( arch_period >= 5000 )
                  {
                   arch_period = arch_period - DELTA_PERIODIC_LONG;
                  }
            else
                  {
#ifdef _TG_WINDOWS_
                  double tmp = (double)arch_period * DELTA_PERIODIC;
                  double int_part,eve_round;
                  double frac = modf(tmp,&int_part);
                  if (frac >= 0.5)
                              eve_round = ceil(tmp);
                  else
                              eve_round = floor(tmp);                         
#else
      #if ((defined __SUNPRO_CC) || (!defined GCC_STD))
                  double eve_round = rint((double)arch_period * DELTA_PERIODIC);
      #else
            #if (defined GCC_SOLARIS)
                  double eve_round = rint((double)arch_period * DELTA_PERIODIC);
            #else
                  double eve_round = round((double)arch_period * DELTA_PERIODIC);
            #endif
      #endif
#endif
                  arch_period = (int)eve_round;
                  }
            
            if ((ms_since_last_periodic > arch_period) && (attr.ext->prev_archive_event.inited == true))
            {
                  is_change = true;
                  period_change = true;
            }
            
//
// if no attribute of this name is registered with change then
// insert the current value
//


            if (!attr.ext->prev_archive_event.inited)
            {
                  if (except != NULL)
                        attr.ext->prev_archive_event.err = true;
                  else
                  {
                        attr.ext->prev_archive_event.value = attr_value.value;
                        attr.ext->prev_archive_event.quality = attr_value.quality;
                        attr.ext->prev_archive_event.err = false;
                  }
                  attr.ext->archive_last_periodic = now_ms;
                  attr.ext->prev_archive_event.inited = true;
            }
            else
            {
      
//
// determine delta_change in percent compared with previous event sent
//

                  if (is_change == false)
                  {
                        is_change = detect_change(attr,attr_value,true,
                                            delta_change_rel,
                                            delta_change_abs,except,
                                            force_change,device_impl);
                        if (is_change == true)
                              value_change = true;
                  }
            }
      
            if (is_change)
            {
                  vector<string> filterable_names;
                  vector<double> filterable_data;
                  vector<string> filterable_names_lg;
                  vector<long> filterable_data_lg;

                  domain_name = device_impl->get_name() + "/" + attr_name;
//                if (value_change == true)
//                {
                  if (except != NULL)
                        attr.ext->prev_archive_event.err = true;
                  else
                  {
                        attr.ext->prev_archive_event.value = attr_value.value;
                        attr.ext->prev_archive_event.quality = attr_value.quality;
                        attr.ext->prev_archive_event.err = false;
                  }
//                }

                  filterable_names_lg.push_back("counter");
                  if (period_change == true)
                  {
                        attr.ext->archive_periodic_counter++;
                        attr.ext->archive_last_periodic = now_ms;
                        filterable_data_lg.push_back(attr.ext->archive_periodic_counter);
                  }
                  else
                  {
                        filterable_data_lg.push_back(-1);
                  }

                  filterable_names.push_back("delta_change_rel");
                  filterable_data.push_back(delta_change_rel);
                  filterable_names.push_back("delta_change_abs");
                  filterable_data.push_back(delta_change_abs);
                  filterable_names.push_back("forced_event");
                  if (force_change == true)
                        filterable_data.push_back((double)1.0);
                  else
                        filterable_data.push_back((double)0.0);         

                  push_event(device_impl,
                           "archive",
                           filterable_names,
                           filterable_data,
                           filterable_names_lg,
                           filterable_data_lg,
                           attr_value,
                           attr_name,
                           except);
            }
      }


//+----------------------------------------------------------------------------
//
// method :             EventSupplier::detect_and_push_quality_change_event()
// 
// description :  Method to detect if there it is necessary
//                to push a quality change event
//
// argument : in :      device_impl : The device
//                attr_value : The attribute value
//                attr : The attribute object
//                attr_name : The attribute name
//                except : The exception thrown during the last
//                       attribute reading. NULL if no exception
//
//-----------------------------------------------------------------------------

      template <typename T>
      void detect_and_push_quality_change_event(DeviceImpl *device_impl,
                                      T &attr_value,
                                      Attribute &attr,
                                      string &attr_name,
                                      DevFailed *except)
      {
            cout3 << "EventSupplier::detect_and_push_quality_change_event(): called for attribute " << attr_name << endl;
            bool is_change = false;
      
//
// if no attribute of this name is registered with change then
// insert the current value
//

            if (!attr.ext->prev_quality_event.inited)
            {
                  if (except != NULL)
                        attr.ext->prev_quality_event.err = true;
                  else
                  {
                        attr.ext->prev_quality_event.quality = attr_value.quality;
                        attr.ext->prev_quality_event.err = false;
                  }
                  attr.ext->prev_quality_event.inited = true;
            }
            else
            {
                  if (except != NULL)
                        is_change = true;
                  else if ((except == NULL) && (attr.ext->prev_quality_event.err == true))
                        is_change = true;
                  else if (attr_value.quality != attr.ext->prev_quality_event.quality)
                        is_change = true;
                  else
                        is_change = false;      
            }
      
//
// Send the event if necessary
//
      
            if (is_change)
            {
                  vector<string> filterable_names;
                  vector<double> filterable_data;
                  vector<string> filterable_names_lg;
                  vector<long> filterable_data_lg;

                  if (except != NULL)
                        attr.ext->prev_quality_event.err = true;
                  else
                  {
                        attr.ext->prev_quality_event.quality = attr_value.quality;
                        attr.ext->prev_quality_event.err = false;
                  }

                  push_event(device_impl,
                           "quality",
                           filterable_names,
                           filterable_data,
                           filterable_names_lg,
                           filterable_data_lg,
                           attr_value,
                           attr_name,
                           except);
            }
      }


//+----------------------------------------------------------------------------
//
// method :             EventSupplier::detect_and_push_periodic_event()
// 
// description :  Method to detect if there it is necessary
//                to push a periodic event
//
// argument : in :      device_impl : The device
//                attr_value : The attribute value
//                attr_value_4 : The attribute value for device implementing IDL 4
//                attr : The attribute object
//                attr_name : The attribute name
//                except : The exception thrown during the last
//                       attribute reading. NULL if no exception
//
//-----------------------------------------------------------------------------

      void detect_and_push_periodic_event_3(DeviceImpl *device_impl,
                                  AttributeValue_3 *attr_value,
                                    AttributeValue_4 *attr_value_4,
                                  Attribute &attr,
                                  string &attr_name,
                                  DevFailed *except,
                                    struct timeval *);
                                  

      template <typename T>
      void detect_and_push_periodic_event(DeviceImpl *device_impl,
                                  T &attr_value,
                                  Attribute &attr,
                                  string &attr_name,
                                  DevFailed *except)
      {
            string event, domain_name;
            double now_ms, ms_since_last_periodic;
#ifdef _TG_WINDOWS_
            struct _timeb           now_win;
#endif
            struct timeval          now_timeval;

#ifdef _TG_WINDOWS_
            _ftime(&now_win);
            now_timeval.tv_sec = (unsigned long)now_win.time;
            now_timeval.tv_usec = (long)now_win.millitm * 1000;
#else
            gettimeofday(&now_timeval,NULL);
#endif

            // get the mutex to synchronize the sending of events
            omni_mutex_lock l(event_mutex);

            now_ms = (double)now_timeval.tv_sec * 1000. + (double)now_timeval.tv_usec / 1000.;

            int eve_period;         
            TangoMonitor &mon1 = device_impl->get_att_conf_monitor();
            mon1.get_monitor();
            eve_period = attr.ext->event_period;
            mon1.rel_monitor();

            // Specify the precision interval for the event period testing
            // 2% are used for periods < 5000 ms and
            // 100ms are used for periods > 5000 ms.
      
            if ( eve_period >= 5000 )
                  {
                   eve_period = eve_period - DELTA_PERIODIC_LONG;
                  }
            else
                  {
#ifdef _TG_WINDOWS_
                  double tmp = (double)eve_period * DELTA_PERIODIC;
                  double int_part,eve_round;
                  double frac = modf(tmp,&int_part);
                  if (frac >= 0.5)
                              eve_round = ceil(tmp);
                  else
                              eve_round = floor(tmp);                         
#else
      #if ((defined __SUNPRO_CC) || (!defined GCC_STD))
                  double eve_round = rint((double)eve_period * DELTA_PERIODIC);
      #else
            #if (defined GCC_SOLARIS)
                  double eve_round = rint((double)eve_period * DELTA_PERIODIC);
            #else
                  double eve_round = round((double)eve_period * DELTA_PERIODIC);
            #endif
      #endif
#endif
                  eve_period = (int)eve_round;
                  }

            ms_since_last_periodic = now_ms - attr.ext->last_periodic;
            cout3 << "EventSupplier::detect_and_push_is_periodic_event(): delta since last periodic " << ms_since_last_periodic << " event_period " << eve_period << " for " << device_impl->get_name()+"/"+attr_name << endl;

            if (ms_since_last_periodic > eve_period)
            {
                  vector<string> filterable_names;
                  vector<double> filterable_data;
                  vector<string> filterable_names_lg;
                  vector<long> filterable_data_lg;

                  attr.ext->periodic_counter++;
                  attr.ext->last_periodic = now_ms;
                  filterable_names_lg.push_back("counter");
                  filterable_data_lg.push_back(attr.ext->periodic_counter);

                  cout3 << "EventSupplier::detect_and_push_is_periodic_event(): detected periodic event for " << device_impl->get_name()+"/"+attr_name << endl;
                  push_event(device_impl,
                           "periodic",
                           filterable_names,
                           filterable_data,
                           filterable_names_lg,
                           filterable_data_lg,
                           attr_value,
                           attr_name,
                           except);
            }

      }

      
//+----------------------------------------------------------------------------
//
// method :             EventSupplier::push_event()
// 
// description :  Method to send the event to the event channel
//
// argument : in :      device_impl : The device
//                event_type : The event type (change, periodic....)
//                filterable_names : 
//                filterable_data :
//                attr_value : The attribute value
//                except : The exception thrown during the last
//                       attribute reading. NULL if no exception
//
//-----------------------------------------------------------------------------

      void push_event_3(DeviceImpl *device_impl,
                        string event_type,
                        vector<string> &filterable_names,
                        vector<double> &filterable_data,
                        vector<string> &filterable_names_lg,
                        vector<long> &filterable_data_lg,
                        AttributeValue_3 *attr_value,
                        AttributeValue_4 *attr_value_4,
                        string &attr_name,
                        DevFailed *except);
                  

      template <typename T>
      void push_event(DeviceImpl *device_impl,
                        string event_type,
                        vector<string> &filterable_names,
                        vector<double> &filterable_data,
                        vector<string> &filterable_names_lg,
                        vector<long> &filterable_data_lg,
                        T &attr_value,
                        string &attr_name,
                        DevFailed *except)
      {
            CosNotification::StructuredEvent struct_event;
            string domain_name;

            cout3 << "EventSupplier::push_event(): called for attribute " << attr_name << endl;
            
            // get the mutex to synchronize the sending of events
            omni_mutex_lock l(push_mutex);
            
            string loc_attr_name = attr_name;   
            transform(loc_attr_name.begin(),loc_attr_name.end(),loc_attr_name.begin(),::tolower);
            domain_name = device_impl->get_name_lower() + "/" + loc_attr_name;

            struct_event.header.fixed_header.event_type.domain_name = CORBA::string_dup(domain_name.c_str());
            struct_event.header.fixed_header.event_type.type_name = CORBA::string_dup(fqdn_prefix.c_str());

            struct_event.header.variable_header.length( 0 );

            unsigned long nb_filter = filterable_names.size();
            unsigned long nb_filter_lg = filterable_names_lg.size();

            struct_event.filterable_data.length(nb_filter + nb_filter_lg);

            if (nb_filter != 0)
            {     
                  if (nb_filter == filterable_data.size())
                  {
                        for (unsigned long i = 0; i < nb_filter; i++)
                        {
                              struct_event.filterable_data[i].name = CORBA::string_dup(filterable_names[i].c_str());
                              struct_event.filterable_data[i].value <<= (CORBA::Double) filterable_data[i];
                        }
                  }
            }

            if (nb_filter_lg != 0)
            {     
                  if (nb_filter_lg == filterable_data_lg.size())
                  {
                        for (unsigned long i = 0; i < nb_filter_lg; i++)
                        {
                              struct_event.filterable_data[i + nb_filter].name = CORBA::string_dup(filterable_names_lg[i].c_str());
                              struct_event.filterable_data[i + nb_filter].value <<= (CORBA::Long) filterable_data_lg[i];
                        }
                  }
            }

            if (except == NULL)     
                  struct_event.remainder_of_body <<= attr_value;
            else
                  struct_event.remainder_of_body <<= except->errors;
            struct_event.header.fixed_header.event_name = CORBA::string_dup(event_type.c_str());

            cout3 << "EventSupplier::push_event(): push event " << event_type << " for " << device_impl->get_name() + "/" + attr_name << endl;

//
// Push the event
//

            bool fail = false;
            try
            {
                  structuredProxyPushConsumer -> push_structured_event(struct_event);
            }
            catch(const CosEventComm::Disconnected&)
            {
                  cout3 << "EventSupplier::push_event() event channel disconnected !\n";
                  fail = true;
            }
      catch(const CORBA::TRANSIENT &)
      {
            cout3 << "EventSupplier::push_event() caught a CORBA::TRANSIENT ! " << endl;
                  fail = true;
      }
      catch(const CORBA::COMM_FAILURE &)
      {
            cout3 << "EventSupplier::push_event() caught a CORBA::COMM_FAILURE ! " << endl;
                  fail = true;
            }
            catch(const CORBA::SystemException &)
            {
            cout3 << "EventSupplier::push_event() caught a CORBA::SystemException ! " << endl;
                  fail = true;
            }
      
//
// If it was not possible to communicate with notifd,
// try a reconnection
//

            if (fail == true)
            {
                  try
                  {
                        reconnect_notifd();
                  }
                  catch (...) {}
            }

      }

};

} // End of namespace


#endif // _EVENT_SUPPLIER_API_H


Generated by  Doxygen 1.6.0   Back to index