Skip to content

Commit 6b69753

Browse files
committed
Fix race condition in async_alert using lock and is_running check
1 parent bf1f8a4 commit 6b69753

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

cmd2/cmd2.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ def _(event: Any) -> None: # pragma: no cover
625625
# This flag is set to True when the prompt is displayed and the application is waiting for user input.
626626
# It is used by async_alert() to determine if it is safe to alert the user.
627627
self._in_prompt = False
628+
self._in_prompt_lock = threading.Lock()
628629

629630
# Commands that have been disabled from use. This is to support commands that are only available
630631
# during specific states of the application. This dictionary's keys are the command names and its
@@ -3349,7 +3350,8 @@ def read_input(
33493350
:raises Exception: any exceptions raised by prompt()
33503351
"""
33513352
self._reset_completion_defaults()
3352-
self._in_prompt = True
3353+
with self._in_prompt_lock:
3354+
self._in_prompt = True
33533355
try:
33543356
if self.use_rawinput and self.stdin.isatty():
33553357
# Determine completer
@@ -3454,7 +3456,8 @@ def get_prompt() -> ANSI | str:
34543456
return line
34553457

34563458
finally:
3457-
self._in_prompt = False
3459+
with self._in_prompt_lock:
3460+
self._in_prompt = False
34583461

34593462
def _read_command_line(self, prompt: str) -> str:
34603463
"""Read command line from appropriate stdin.
@@ -5519,8 +5522,9 @@ def async_alert(self, alert_msg: str, new_prompt: str | None = None) -> None:
55195522
:raises RuntimeError: if main thread is not currently at the prompt.
55205523
"""
55215524
# Check if prompt is currently displayed and waiting for user input
5522-
if not self._in_prompt:
5523-
raise RuntimeError("Main thread is not at the prompt")
5525+
with self._in_prompt_lock:
5526+
if not self._in_prompt or not self.session.app.is_running:
5527+
raise RuntimeError("Main thread is not at the prompt")
55245528

55255529
def _alert() -> None:
55265530
if new_prompt is not None:

0 commit comments

Comments
 (0)