From a7bbcd1360ca6f0e1235da7c7c1ddc65628f4f2b Mon Sep 17 00:00:00 2001 From: Antoine Prieels Date: Mon, 13 Jul 2020 14:20:39 +0000 Subject: [PATCH] hw_drivers: Stop devices threads on disconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The threads of devices were still running after `disconnect` had been called. We add a `_stopped` flag that is set when the thread should be stopped. closes odoo/odoo#56500 X-original-commit: 639a4e4fc72567a9655599eef150fabefaf1ff2e Related: odoo/enterprise#12651 Signed-off-by: Quentin Lejeune (qle) Signed-off-by: Antoine Prieƫls --- addons/hw_drivers/driver.py | 4 +++- addons/hw_drivers/iot_handlers/drivers/DisplayDriver.py | 2 +- addons/hw_drivers/iot_handlers/drivers/KeyboardUSBDriver.py | 2 ++ addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/hw_drivers/driver.py b/addons/hw_drivers/driver.py index bfe60effc6b..459c3c9b24d 100644 --- a/addons/hw_drivers/driver.py +++ b/addons/hw_drivers/driver.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from threading import Thread +from threading import Thread, Event from odoo.addons.hw_drivers.main import drivers, iot_devices @@ -32,6 +32,7 @@ class Driver(Thread, metaclass=DriverMetaClass): self.device_type = '' self.device_manufacturer = '' self.data = {'value': ''} + self._stopped = Event() @classmethod def supported(cls, device): @@ -48,4 +49,5 @@ class Driver(Thread, metaclass=DriverMetaClass): raise NotImplementedError() def disconnect(self): + self._stopped.set() del iot_devices[self.device_identifier] diff --git a/addons/hw_drivers/iot_handlers/drivers/DisplayDriver.py b/addons/hw_drivers/iot_handlers/drivers/DisplayDriver.py index 98854b98885..0b79dd5b3cc 100644 --- a/addons/hw_drivers/iot_handlers/drivers/DisplayDriver.py +++ b/addons/hw_drivers/iot_handlers/drivers/DisplayDriver.py @@ -70,7 +70,7 @@ class DisplayDriver(Driver): event_manager.device_changed(self) def run(self): - while self.device_identifier != 'distant_display': + while self.device_identifier != 'distant_display' and not self._stopped.isSet(): time.sleep(60) if self.url != 'http://localhost:8069/point_of_sale/display/' + self.device_identifier: # Refresh the page every minute diff --git a/addons/hw_drivers/iot_handlers/drivers/KeyboardUSBDriver.py b/addons/hw_drivers/iot_handlers/drivers/KeyboardUSBDriver.py index 8c27f20b569..29c7b12b92c 100644 --- a/addons/hw_drivers/iot_handlers/drivers/KeyboardUSBDriver.py +++ b/addons/hw_drivers/iot_handlers/drivers/KeyboardUSBDriver.py @@ -135,6 +135,8 @@ class KeyboardUSBDriver(Driver): def run(self): try: for event in self.input_device.read_loop(): + if self._stopped.isSet(): + break if event.type == evdev.ecodes.EV_KEY: data = evdev.categorize(event) diff --git a/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py b/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py index 6c3f1ceebb7..412d773e8c2 100644 --- a/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py +++ b/addons/hw_drivers/iot_handlers/drivers/SerialBaseDriver.py @@ -134,7 +134,7 @@ class SerialDriver(Driver): self._connection = connection self._status['status'] = self.STATUS_CONNECTED self._push_status() - while True: + while not self._stopped.isSet(): self._take_measure() time.sleep(self._protocol.newMeasureDelay) except Exception: