Memory management in event consumer

Hi

I have two question about Tango::CallBack’s push_event(Tango::EventData *myevent) method:

  1. After processed myevent,if i need to free *myevent or not? or free myevent->attr_value?

as documentation (http://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/ds_prog/node7.html#SECTION00785000000000000000) says: i should “delete myevent->attr_value” after processed myevent

[quote]6.8.5 Tango::EventData
Memory has been allocated for the vector of DeviceAttribute objects passed to the caller. This is the caller responsibility to delete this memory.[/quote]

  1. My Attribute is DevLong data type, but why “long_value->length()” return 2, and (*long_value)[1] is alway 0. I want to khnow what is (*long_value)[1] meaning? it is a terminator,or it is attribute’s write value??
class MyValueCallback : public Tango::CallBack
{
  void push_event(Tango::EventData *myevent)  //virtual,overload
  {
    Tango::DevVarLongArray *long_value; // Attribute is DevLong type
    try{
      if (!myevent->err){
	*(myevent->attr_value) >> long_value;
        // 2 == long_value->length(); //why return 2  ???
	cout << " Value1 = " << (*long_value)[0] << endl;
	delete long_value;
      }
    }
    catch (...){
      // ...
    }
    // if i need to  delete myevent; or delete myevent->attr_value; ???
  }
}

MyValueCallback *mycb = new MyValueCallback();
event_idp = dev.subscribe_event(att_devlong_name,
	Tango::PERIODIC_EVENT,mycb);

I have another quesiton about memory management in event pull process: how to free memeory allocated by get_events() method?

while(true)
{
  // other process ...

  // It's time to process event	in buffer
  Tango::EventDataList el;
  dev.get_events(event_idp, el);  //read all sub event from buffer

  Tango::EventDataList::iterator vpos;
  Tango::DevVarLongArray *long_value;
  for(vpos=el.begin(); vpos!=el.end(); ++vpos)
  {
    if (!(*vpos)->err) //vpos is a pointer to EventData*
    {
      *((*vpos)->attr_value) >> long_value;
      cout << " Value1 = " << (*long_value)[0] << endl;
      delete long_value;
    }
  }//end for
  el.clear();// clear() is needed? if it free all memory allocated by get_events?
}//end while

Thanks

Hi Jimmy,

I try to answer to your three (not two!) questions:
1 - The doc is wrong! Good catch! It’s not at all necessary to delete this memory. In this case, it is fully handled by
the library
2 - I assume your attribute is READ_WRITE. When you read this kind of attribute, you received two values which are:

  • The read value
  • The last written value

This allows the client to check any in-coherency between the set value and the read value (For instance a Power Supply to which
you ask a current of 10 Amp and which delivers only 9.97 Amp)
3 - For the event in the Pull model: Your “el.clear()” is not required (done by the lib) while your “delete long_value” is required
because you extract data from the DeviceAttribute object with a Tango sequence pointer.
Don’t forget to un-subscribe to the event because the event queue itself is freed at that moment (while it is something done
only once and therefore does not generate a real leak)

Hoping this help

Emmanuel

Re,

Oups sorry!! I did not see in your code snippet associated to your first question that you extract data from the
DeviceAttribute by ptr and in this case yes, you have to delete the memory. If you extract the data in classic scalar data type
or in a vector, you don’t have to do specific memory management. See doc on DeviceAttribute class insertor/extractors methods.

Cheers

Emmanuel

Hi Manu

Thank you for your guidance

As you say, my device attribute is READ_WRITE, so i received two values in DeviceAttribute.

but i can’t know excatly the meaning of :

[quote=“Manu”]Re,

you extract data from the DeviceAttribute by ptr and in this case yes, you have to delete the memory. If you extract the data in classic scalar data type or in a vector, you don’t have to do specific memory management.
[/quote]

whether is mean i must add this line:

delete myevent->attr_value

in code snippet 1 after processed myevent

class MyValueCallback : public Tango::CallBack
{
  void push_event(Tango::EventData *myevent)  //virtual,overload
  {
    Tango::DevVarLongArray *long_value; // Attribute is DevLong type
    try{
      if (!myevent->err){
	*(myevent->attr_value) >> long_value;
	cout << " Value1 = " << (*long_value)[0] << endl;
	delete long_value;
        delete myevent->attr_value; // must add this line ???
      }
    }
    catch (…){
      // …
    }
  }
}

thanks

Hi Jimmy,

The line “delete myevent->attr_value” is not required.

Cheers

Emmanuel

Hi Manu.

Thank you for your guidance.

Thanks and Regards
Jimmy