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.
This commit is contained in:
parent
0c084c89fe
commit
a874235dff
1 changed files with 9 additions and 2 deletions
|
@ -6,7 +6,7 @@ from xml.sax.saxutils import XMLGenerator
|
||||||
from colorama import Style
|
from colorama import Style
|
||||||
import queue
|
import queue
|
||||||
import io
|
import io
|
||||||
import _thread
|
import threading
|
||||||
import argparse
|
import argparse
|
||||||
import atexit
|
import atexit
|
||||||
import base64
|
import base64
|
||||||
|
@ -409,6 +409,7 @@ class Machine:
|
||||||
pid: Optional[int] = None
|
pid: Optional[int] = None
|
||||||
monitor: Optional[socket.socket] = None
|
monitor: Optional[socket.socket] = None
|
||||||
shell: Optional[socket.socket] = None
|
shell: Optional[socket.socket] = None
|
||||||
|
serial_thread: Optional[threading.Thread]
|
||||||
|
|
||||||
booted: bool = False
|
booted: bool = False
|
||||||
connected: bool = False
|
connected: bool = False
|
||||||
|
@ -444,6 +445,8 @@ class Machine:
|
||||||
self.cleanup_statedir()
|
self.cleanup_statedir()
|
||||||
self.state_dir.mkdir(mode=0o700, exist_ok=True)
|
self.state_dir.mkdir(mode=0o700, exist_ok=True)
|
||||||
|
|
||||||
|
self.serial_thread = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_startcommand(args: Dict[str, str]) -> StartCommand:
|
def create_startcommand(args: Dict[str, str]) -> StartCommand:
|
||||||
rootlog.warning(
|
rootlog.warning(
|
||||||
|
@ -921,7 +924,8 @@ class Machine:
|
||||||
self.last_lines.put(line)
|
self.last_lines.put(line)
|
||||||
self.log_serial(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()
|
self.wait_for_monitor_prompt()
|
||||||
|
|
||||||
|
@ -1021,9 +1025,12 @@ class Machine:
|
||||||
assert self.process
|
assert self.process
|
||||||
assert self.shell
|
assert self.shell
|
||||||
assert self.monitor
|
assert self.monitor
|
||||||
|
assert self.serial_thread
|
||||||
|
|
||||||
self.process.terminate()
|
self.process.terminate()
|
||||||
self.shell.close()
|
self.shell.close()
|
||||||
self.monitor.close()
|
self.monitor.close()
|
||||||
|
self.serial_thread.join()
|
||||||
|
|
||||||
|
|
||||||
class VLan:
|
class VLan:
|
||||||
|
|
Loading…
Reference in a new issue