C++: Fix management of SessionDevice objects.

This commit is contained in:
Martin Ling 2014-09-30 16:05:27 +01:00
parent 584f76a78a
commit ca4e307a93
2 changed files with 32 additions and 8 deletions

View File

@ -725,7 +725,7 @@ DatafeedCallbackData::DatafeedCallbackData(Session *session,
void DatafeedCallbackData::run(const struct sr_dev_inst *sdi, void DatafeedCallbackData::run(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *pkt) const struct sr_datafeed_packet *pkt)
{ {
auto device = _session->_devices[sdi]; auto device = _session->get_device(sdi);
auto packet = shared_ptr<Packet>(new Packet(device, pkt), Packet::Deleter()); auto packet = shared_ptr<Packet>(new Packet(device, pkt), Packet::Deleter());
_callback(device, packet); _callback(device, packet);
} }
@ -814,9 +814,7 @@ Session::Session(shared_ptr<Context> context, string filename) :
for (GSList *dev = dev_list; dev; dev = dev->next) for (GSList *dev = dev_list; dev; dev = dev->next)
{ {
auto sdi = (struct sr_dev_inst *) dev->data; auto sdi = (struct sr_dev_inst *) dev->data;
auto device = new SessionDevice(sdi); _owned_devices[sdi] = new SessionDevice(sdi);
_devices[sdi] = shared_ptr<SessionDevice>(device,
SessionDevice::Deleter());
} }
_context->_session = this; _context->_session = this;
} }
@ -830,12 +828,26 @@ Session::~Session()
for (auto entry : _source_callbacks) for (auto entry : _source_callbacks)
delete entry.second; delete entry.second;
for (auto entry : _owned_devices)
delete entry.second;
}
shared_ptr<Device> Session::get_device(const struct sr_dev_inst *sdi)
{
if (_owned_devices.count(sdi))
return static_pointer_cast<Device>(
_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> device) void Session::add_device(shared_ptr<Device> device)
{ {
check(sr_session_dev_add(_structure, device->_structure)); check(sr_session_dev_add(_structure, device->_structure));
_devices[device->_structure] = device; _other_devices[device->_structure] = device;
} }
vector<shared_ptr<Device>> Session::devices() vector<shared_ptr<Device>> Session::devices()
@ -846,14 +858,24 @@ vector<shared_ptr<Device>> Session::devices()
for (GSList *dev = dev_list; dev; dev = dev->next) for (GSList *dev = dev_list; dev; dev = dev->next)
{ {
auto sdi = (struct sr_dev_inst *) dev->data; auto sdi = (struct sr_dev_inst *) dev->data;
result.push_back(_devices[sdi]); result.push_back(get_device(sdi));
} }
return result; return result;
} }
void Session::remove_devices() 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)); check(sr_session_dev_remove_all(_structure));
} }

View File

@ -668,8 +668,10 @@ protected:
Session(shared_ptr<Context> context); Session(shared_ptr<Context> context);
Session(shared_ptr<Context> context, string filename); Session(shared_ptr<Context> context, string filename);
~Session(); ~Session();
shared_ptr<Device> get_device(const struct sr_dev_inst *sdi);
const shared_ptr<Context> _context; const shared_ptr<Context> _context;
map<const struct sr_dev_inst *, shared_ptr<Device> > _devices; map<const struct sr_dev_inst *, SessionDevice *> _owned_devices;
map<const struct sr_dev_inst *, shared_ptr<Device> > _other_devices;
vector<DatafeedCallbackData *> _datafeed_callbacks; vector<DatafeedCallbackData *> _datafeed_callbacks;
map<shared_ptr<EventSource>, SourceCallbackData *> _source_callbacks; map<shared_ptr<EventSource>, SourceCallbackData *> _source_callbacks;
bool _saving; bool _saving;