motion_report: Ensure startstop_cb is called atomically

Make sure APIDumpHelper() does not invoke the startstop callback while
it is already running.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-02-21 22:12:53 -05:00
parent 2b2caa8f05
commit b0a24a4458
1 changed files with 12 additions and 4 deletions

View File

@ -17,29 +17,37 @@ class APIDumpHelper:
if startstop_cb is None: if startstop_cb is None:
startstop_cb = (lambda is_start: None) startstop_cb = (lambda is_start: None)
self.startstop_cb = startstop_cb self.startstop_cb = startstop_cb
self.is_started = False
self.update_interval = update_interval self.update_interval = update_interval
self.update_timer = None self.update_timer = None
self.clients = {} self.clients = {}
def _stop(self): def _stop(self):
self.clients.clear() self.clients.clear()
if self.update_timer is None:
return
reactor = self.printer.get_reactor() reactor = self.printer.get_reactor()
reactor.unregister_timer(self.update_timer) reactor.unregister_timer(self.update_timer)
self.update_timer = None self.update_timer = None
if not self.is_started:
return reactor.NEVER
try: try:
self.startstop_cb(False) self.startstop_cb(False)
except self.printer.command_error as e: except self.printer.command_error as e:
logging.exception("API Dump Helper stop callback error") logging.exception("API Dump Helper stop callback error")
self.clients.clear()
self.is_started = False
if self.clients:
# New client started while in process of stopping
self._start()
return reactor.NEVER return reactor.NEVER
def _start(self): def _start(self):
if self.update_timer is not None: if self.is_started:
return return
self.is_started = True
try: try:
self.startstop_cb(True) self.startstop_cb(True)
except self.printer.command_error as e: except self.printer.command_error as e:
logging.exception("API Dump Helper start callback error") logging.exception("API Dump Helper start callback error")
self._stop() self.is_started = False
self.clients.clear()
raise raise
reactor = self.printer.get_reactor() reactor = self.printer.get_reactor()
systime = reactor.monotonic() systime = reactor.monotonic()