Fix #605 by closing current device when another is selected
authorSoeren Apel <soeren@apelpie.net>
Fri, 4 Sep 2015 01:34:08 +0000 (03:34 +0200)
committerSoeren Apel <soeren@apelpie.net>
Fri, 4 Sep 2015 01:34:08 +0000 (03:34 +0200)
As the device manager class holds a pointer to all devices
they will never be destroyed until PV exits. Devices are
opened with the first call to create() but only closed in
the destructor. Together, this results in devices never
being closed.

This patch fixes this by renaming create() to open()
and introducing a matching close() method that the
session class calls when a different device is to be
selected.

pv/devices/device.hpp
pv/devices/hardwaredevice.cpp
pv/devices/hardwaredevice.hpp
pv/devices/inputfile.cpp
pv/devices/inputfile.hpp
pv/devices/sessionfile.cpp
pv/devices/sessionfile.hpp
pv/session.cpp

index 0a8f2438decc86fd9f592c2b92cdf89ba3f25236..acc772ecc5eaab8aed2ccc746f0e9911cc42590b 100644 (file)
@@ -64,7 +64,9 @@ public:
        virtual std::string display_name(
                const DeviceManager &device_manager) const = 0;
 
-       virtual void create() = 0;
+       virtual void open() = 0;
+
+       virtual void close() = 0;
 
        virtual void start();
 
index b98b0e02f8aa9b2e43756af75835d8bae55723b4..d1161aa26669a614bc36fc52e4871bdc1fb68496 100644 (file)
@@ -49,11 +49,7 @@ HardwareDevice::HardwareDevice(const std::shared_ptr<sigrok::Context> &context,
 }
 
 HardwareDevice::~HardwareDevice() {
-       if (device_open_)
-               device_->close();
-
-       if (session_)
-               session_->remove_devices();
+       close();
 }
 
 string HardwareDevice::full_name() const {
@@ -99,8 +95,10 @@ string HardwareDevice::display_name(
        return join(parts, " ");
 }
 
-void HardwareDevice::create() {
-       // Open the device
+void HardwareDevice::open() {
+       if (device_open_)
+               close();
+
        try {
                device_->open();
        } catch(const sigrok::Error &e) {
@@ -114,5 +112,15 @@ void HardwareDevice::create() {
        session_->add_device(device_);
 }
 
+void HardwareDevice::close() {
+       if (device_open_)
+               device_->close();
+
+       if (session_)
+               session_->remove_devices();
+
+       device_open_ = false;
+}
+
 } // namespace devices
 } // namespace pv
index df11ed25783caa8221fb269a6b0b60fff3554eec..bc8e47a589c9640e2828d1c16b80293c49e80ce5 100644 (file)
@@ -53,7 +53,9 @@ public:
         */
        std::string display_name(const DeviceManager &device_manager) const;
 
-       void create();
+       void open();
+
+       void close();
 
 private:
        const std::shared_ptr<sigrok::Context> context_;
index e92bf208bf17989039bed7b4dbbbbe277f49093f..13af3db9cd85c791935da6c80bf1a14220d492a0 100644 (file)
@@ -42,10 +42,18 @@ InputFile::InputFile(const std::shared_ptr<sigrok::Context> &context,
                throw QString("Failed to create input");
 }
 
-void InputFile::create() {
+void InputFile::open() {
+       if (session_)
+               close();
+
        session_ = context_->create_session();
 }
 
+void InputFile::close() {
+       if (session_)
+               session_->remove_devices();
+}
+
 void InputFile::start() {
 }
 
index 588ccdf243e39c87ca52583678249b17cb42167e..9b9aee88dcbad288f12642397a6b6921d9e83a29 100644 (file)
@@ -41,7 +41,9 @@ public:
                std::shared_ptr<sigrok::InputFormat> format,
                const std::map<std::string, Glib::VariantBase> &options);
 
-       void create();
+       void open();
+
+       void close();
 
        void start();
 
index d45b9fa492832bc147c7ea7aadcc8e06c446d263..e6920ff5e299a6a5b5e437b2768d3d020549f2e0 100644 (file)
@@ -33,10 +33,18 @@ SessionFile::SessionFile(const std::shared_ptr<sigrok::Context> context,
        context_(context) {
 }
 
-void SessionFile::create() {
+void SessionFile::open() {
+       if (session_)
+               close();
+
        session_ = context_->load_session(file_name_);
        device_ = session_->devices()[0];
 }
 
+void SessionFile::close() {
+       if (session_)
+               session_->remove_devices();
+}
+
 } // namespace devices
 } // namespace pv
index 0a546f0cc598be88747ebfe57cf0aec5138d3597..9494571440e7765e97c97d5e40145d7333d014e2 100644 (file)
@@ -38,7 +38,9 @@ public:
        SessionFile(const std::shared_ptr<sigrok::Context> context,
                const std::string &file_name);
 
-       void create();
+       void open();
+
+       void close();
 
 private:
        const std::shared_ptr<sigrok::Context> context_;
index 22e0428d94abf26a5421c540377dc9e55c6ddccf..4823543213de5b5a080be2ea732d1086aefa4bae 100644 (file)
@@ -127,8 +127,11 @@ void Session::set_device(shared_ptr<devices::Device> device)
        // Ensure we are not capturing before setting the device
        stop_capture();
 
+       if (device_)
+               device_->close();
+
        device_ = std::move(device);
-       device_->create();
+       device_->open();
        device_->session()->add_datafeed_callback([=]
                (shared_ptr<sigrok::Device> device, shared_ptr<Packet> packet) {
                        data_feed_in(device, packet);