Pushing event from read method leads to crash at subscription

This code crashes (both in boost and pybind11):


from tango import EventType
from tango.server import Device, attribute
from tango.test_context import DeviceTestContext

class MyDevice(Device):

    def init_device(self):
        super(MyDevice, self).init_device()
        self.set_change_event("attr", True, False)

    @attribute()
    def attr(self):
        self.push_change_event("attr", 1)
        return 1


def cb(evnt):
    pass

if __name__ == '__main__':
    with(DeviceTestContext(MyDevice)) as proxy:
        eid = proxy.subscribe_event("attr", EventType.CHANGE_EVENT, cb)

The same code in cpp - does not:


#include "catch2_common.h"

template <class Base>
class EventDev : public Base
{
public:
    using Base::Base;

    ~EventDev() override { }

    void init_device() override
    {
        Base::set_change_event("attr", true, false);
    }

    void read_attribute(Tango::Attribute &att)
    {
        Tango::DevLong* val = new Tango::DevLong(1);
        att.set_value(val, 1, 0, true);
        att.fire_change_event(nullptr);

        Tango::DevLong* val_ret = new Tango::DevLong(1);
        att.set_value(val_ret);
    }

    static void attribute_factory(std::vector<Tango::Attr *> &attrs)
    {
        {
            auto long_attr = new TangoTest::AutoAttr<&EventDev::read_attribute>("attr", Tango::DEV_LONG);
            attrs.push_back(long_attr);
        }
    }
};

TANGO_TEST_AUTO_DEV_TMPL_INSTANTIATE(EventDev, 4)

SCENARIO("Subscribe to event with simultaneous push")
{
    int idlver = GENERATE(TangoTest::idlversion(4));
    GIVEN("a device proxy to a simple IDLv" << idlver << " device")
    {
        TangoTest::Context ctx{"change_event_state", "EventDev", idlver};
        auto device = ctx.get_proxy();

        REQUIRE(idlver == device->get_idl_version());

        AND_GIVEN("an event subscription to attr attribute")
        {
            TangoTest::CallbackMock<Tango::EventData> callback;
            REQUIRE_NOTHROW(device->subscribe_event("attr", Tango::CHANGE_EVENT, &callback));
        }
    }
}

Either cpp code is not 100% equal, or it is pytango bug

Assignee Loading
Time tracking Loading