serialhdl: Use reactor mutex in send_with_response()

Reduce the delay in send_with_response() by introducing a reactor
mutex to wake the main thread when the response is obtained.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-06-09 19:12:24 -04:00
parent 30d2ae8f9f
commit 97840f9851
1 changed files with 20 additions and 12 deletions

View File

@ -44,9 +44,9 @@ class SerialReader:
params['#sent_time'] = response.sent_time
params['#receive_time'] = response.receive_time
hdl = (params['#name'], params.get('oid'))
try:
with self.lock:
hdl = self.handlers.get(hdl, self.handle_default)
try:
hdl(params)
except:
logging.exception("Exception in serial callback")
@ -197,28 +197,36 @@ class SerialRetryCommand:
self.name = name
self.oid = oid
self.response = None
reactor = self.serial.reactor
self.mutex = reactor.mutex(is_locked=True)
self.min_query_time = self.serial.reactor.monotonic()
self.serial.register_callback(self.handle_callback, self.name, self.oid)
self.send_timer = self.serial.reactor.register_timer(
self.send_event, self.serial.reactor.NOW)
retry_time = self.send_event(self.min_query_time)
self.send_timer = reactor.register_timer(self.send_event, retry_time)
def unregister(self):
self.serial.unregister_callback(self.name, self.oid)
self.serial.reactor.unregister_timer(self.send_timer)
def send_event(self, eventtime):
if self.response is not None:
return self.serial.reactor.NEVER
if eventtime > self.min_query_time + self.TIMEOUT_TIME:
self.unregister()
if self.response is None:
self.mutex.unlock()
return self.serial.reactor.NEVER
self.serial.raw_send(self.cmd, 0, 0, self.serial.default_cmd_queue)
return eventtime + self.RETRY_TIME
def handle_callback(self, params):
last_sent_time = params['#sent_time']
if last_sent_time >= self.min_query_time:
if last_sent_time >= self.min_query_time and self.response is None:
self.response = params
self.serial.reactor.register_async_callback(self.do_wake)
def do_wake(self, eventtime):
self.mutex.unlock()
def get_response(self):
eventtime = self.serial.reactor.monotonic()
while self.response is None:
eventtime = self.serial.reactor.pause(eventtime + 0.05)
if eventtime > self.min_query_time + self.TIMEOUT_TIME:
self.unregister()
with self.mutex:
pass
if self.response is None:
raise error("Timeout on wait for '%s' response" % (self.name,))
self.unregister()
return self.response