From 1c079ba16dfd3a195ccb4cc812ea52a09e195395 Mon Sep 17 00:00:00 2001 From: BrenBarn Date: Wed, 12 Oct 2016 23:13:43 -0700 Subject: [PATCH] An attempt at solving the redoubtable "subprocess busy" bug. I don't think it works though. --- dreampielib/gui/__init__.py | 25 +++++++++++++++++++++---- dreampielib/gui/common.py | 3 ++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/dreampielib/gui/__init__.py b/dreampielib/gui/__init__.py index 639f82e..8e97e63 100644 --- a/dreampielib/gui/__init__.py +++ b/dreampielib/gui/__init__.py @@ -873,7 +873,7 @@ def call_subp_noblock(self, funcname, *args): return self.subp.recv_object() else: self._n_unclaimed_results += 1 - raise TimeoutError + raise TimeoutError(while_receiving=True) def call_subp_catch(self, funcname, *args): """ @@ -888,6 +888,23 @@ def call_subp_catch(self, funcname, *args): except TimeoutError: return None + def _call_subp_catch_internal(self, funcname, *args): + """ + We make a non-blocking call, but if a timeout is raised while waiting + for the result, we patch it up by decrementing _n_unclaimed_results. + This MIGHT fix a nasty bug whereby if the timeout is raised while + we wait for attribute completion, we get "stuck" thinking we have to + wait for a computation result that will never come. + """ + if self.is_executing: + return None + try: + return self.call_subp_noblock(funcname, *args) + except TimeoutError as e: + if e.while_receiving: + self._n_unclaimed_results -= 1 + return None + def on_object_recv(self, obj): if self._n_unclaimed_results: self._n_unclaimed_results -= 1 @@ -1220,13 +1237,13 @@ def on_show_completions(self, _widget): self.autocomplete.show_completions(is_auto=False, complete=False) def complete_dict_keys(self, expr): - return self.call_subp_catch(u'complete_dict_keys', expr) + return self._call_subp_catch_internal(u'complete_dict_keys', expr) def complete_attributes(self, expr): - return self.call_subp_catch(u'complete_attributes', expr) + return self._call_subp_catch_internal(u'complete_attributes', expr) def complete_firstlevels(self): - return self.call_subp_catch(u'complete_firstlevels') + return self._call_subp_catch_internal(u'complete_firstlevels') def get_func_args(self, expr): return self.call_subp_catch(u'get_func_args', expr) diff --git a/dreampielib/gui/common.py b/dreampielib/gui/common.py index 8c85120..a438df5 100644 --- a/dreampielib/gui/common.py +++ b/dreampielib/gui/common.py @@ -30,4 +30,5 @@ def get_text(textbuffer, *args): return textbuffer.get_text(*args).decode('utf8') class TimeoutError(Exception): - pass + def __init__(self, while_receiving=False): + self.while_receiving = while_receiving