diff options
author | K900 <me@0upti.me> | 2021-10-19 15:42:27 +0300 |
---|---|---|
committer | K900 <me@0upti.me> | 2021-10-19 16:23:51 +0300 |
commit | a874235dff32bd77125034cfd9542a91b68efb03 (patch) | |
tree | e3671142191b84bd8eaf9d299e1fa77e8aa6f66b /nixos/lib/test-driver | |
parent | 0c084c89fe6406b1d76e448f234a206d9a23f837 (diff) | |
download | nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar.gz nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar.bz2 nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar.lz nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar.xz nixlib-a874235dff32bd77125034cfd9542a91b68efb03.tar.zst nixlib-a874235dff32bd77125034cfd9542a91b68efb03.zip |
nixos/lib/test-driver: clean up threads correctly
The current implementation just forks off a thread to read QEMU's stdout and lets it exist forever. This, however, makes the interpreter shutdown racy, as the thread could still be running and writing out buffered stdout when the main thread exits (and since it's using the low level API, the worker thread does not get cleaned up by the atexit hooks installed by `threading`, either). So, instead of doing that, let's create a real `threading.Thread` object, and also explicitly `join` it along with the other stuff when cleaning up.
Diffstat (limited to 'nixos/lib/test-driver')
-rwxr-xr-x | nixos/lib/test-driver/test-driver.py | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py index e659b0c04f50..f2e7bf3c1d5b 100755 --- a/nixos/lib/test-driver/test-driver.py +++ b/nixos/lib/test-driver/test-driver.py @@ -6,7 +6,7 @@ from xml.sax.saxutils import XMLGenerator from colorama import Style import queue import io -import _thread +import threading import argparse import atexit import base64 @@ -409,6 +409,7 @@ class Machine: pid: Optional[int] = None monitor: Optional[socket.socket] = None shell: Optional[socket.socket] = None + serial_thread: Optional[threading.Thread] booted: bool = False connected: bool = False @@ -444,6 +445,8 @@ class Machine: self.cleanup_statedir() self.state_dir.mkdir(mode=0o700, exist_ok=True) + self.serial_thread = None + @staticmethod def create_startcommand(args: Dict[str, str]) -> StartCommand: rootlog.warning( @@ -921,7 +924,8 @@ class Machine: self.last_lines.put(line) self.log_serial(line) - _thread.start_new_thread(process_serial_output, ()) + self.serial_thread = threading.Thread(target=process_serial_output) + self.serial_thread.start() self.wait_for_monitor_prompt() @@ -1021,9 +1025,12 @@ class Machine: assert self.process assert self.shell assert self.monitor + assert self.serial_thread + self.process.terminate() self.shell.close() self.monitor.close() + self.serial_thread.join() class VLan: |