From: Martin Ling Date: Tue, 30 Sep 2014 15:05:27 +0000 (+0100) Subject: C++: Fix management of SessionDevice objects. X-Git-Tag: libsigrok-0.4.0~911 X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=ca4e307a934ba395bdc3e2a48b83835d05a047c2 C++: Fix management of SessionDevice objects. --- diff --git a/bindings/cxx/classes.cpp b/bindings/cxx/classes.cpp index 66b79a93..86d0865e 100644 --- a/bindings/cxx/classes.cpp +++ b/bindings/cxx/classes.cpp @@ -725,7 +725,7 @@ DatafeedCallbackData::DatafeedCallbackData(Session *session, void DatafeedCallbackData::run(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *pkt) { - auto device = _session->_devices[sdi]; + auto device = _session->get_device(sdi); auto packet = shared_ptr(new Packet(device, pkt), Packet::Deleter()); _callback(device, packet); } @@ -814,9 +814,7 @@ Session::Session(shared_ptr context, string filename) : for (GSList *dev = dev_list; dev; dev = dev->next) { auto sdi = (struct sr_dev_inst *) dev->data; - auto device = new SessionDevice(sdi); - _devices[sdi] = shared_ptr(device, - SessionDevice::Deleter()); + _owned_devices[sdi] = new SessionDevice(sdi); } _context->_session = this; } @@ -830,12 +828,26 @@ Session::~Session() for (auto entry : _source_callbacks) delete entry.second; + + for (auto entry : _owned_devices) + delete entry.second; +} + +shared_ptr Session::get_device(const struct sr_dev_inst *sdi) +{ + if (_owned_devices.count(sdi)) + return static_pointer_cast( + _owned_devices[sdi]->get_shared_pointer(this)); + else if (_other_devices.count(sdi)) + return _other_devices[sdi]; + else + throw Error(SR_ERR_BUG); } void Session::add_device(shared_ptr device) { check(sr_session_dev_add(_structure, device->_structure)); - _devices[device->_structure] = device; + _other_devices[device->_structure] = device; } vector> Session::devices() @@ -846,14 +858,24 @@ vector> Session::devices() for (GSList *dev = dev_list; dev; dev = dev->next) { auto sdi = (struct sr_dev_inst *) dev->data; - result.push_back(_devices[sdi]); + result.push_back(get_device(sdi)); } return result; } void Session::remove_devices() { - _devices.clear(); + for (auto entry : _owned_devices) + { + // We own this device. Make sure it's not referenced. + auto device = entry.second; + auto ptr = device->get_shared_pointer(this); + if (ptr.use_count() > 1) + throw Error(SR_ERR_BUG); + delete device; + } + _owned_devices.clear(); + _other_devices.clear(); check(sr_session_dev_remove_all(_structure)); } diff --git a/bindings/cxx/include/libsigrok/libsigrok.hpp b/bindings/cxx/include/libsigrok/libsigrok.hpp index e30fd4d3..0bf19015 100644 --- a/bindings/cxx/include/libsigrok/libsigrok.hpp +++ b/bindings/cxx/include/libsigrok/libsigrok.hpp @@ -668,8 +668,10 @@ protected: Session(shared_ptr context); Session(shared_ptr context, string filename); ~Session(); + shared_ptr get_device(const struct sr_dev_inst *sdi); const shared_ptr _context; - map > _devices; + map _owned_devices; + map > _other_devices; vector _datafeed_callbacks; map, SourceCallbackData *> _source_callbacks; bool _saving;