Compare commits

..

2 commits

Author SHA1 Message Date
7a479aa6f8
Merge 4f4c523450 into eb345562da 2024-12-19 09:14:23 +00:00
Alexis Métaireau
4f4c523450
Use a separate thread to read stderr when needed 2024-12-19 10:14:13 +01:00
3 changed files with 10 additions and 17 deletions

View file

@ -46,7 +46,8 @@ def print_header(s: str) -> None:
"--debug", "--debug",
"debug", "debug",
flag_value=True, flag_value=True,
help="Run Dangerzone in debug mode, to get logs from gVisor.") help="Run Dangerzone in debug mode, to get logs from gVisor.",
)
@click.version_option(version=get_version(), message="%(version)s") @click.version_option(version=get_version(), message="%(version)s")
@errors.handle_document_errors @errors.handle_document_errors
def cli_main( def cli_main(

View file

@ -6,8 +6,8 @@ import signal
import subprocess import subprocess
import sys import sys
import threading import threading
from queue import Queue
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from queue import Queue
from typing import IO, Callable, Iterator, Optional from typing import IO, Callable, Iterator, Optional
import fitz import fitz
@ -94,7 +94,7 @@ class IsolationProvider(ABC):
self.proc_stderr = subprocess.PIPE self.proc_stderr = subprocess.PIPE
else: else:
self.proc_stderr = subprocess.DEVNULL self.proc_stderr = subprocess.DEVNULL
self.stderr_queue = Queue() self.stderr_queue: Queue = Queue()
def should_capture_stderr(self) -> bool: def should_capture_stderr(self) -> bool:
return self.debug or getattr(sys, "dangerzone_dev", False) return self.debug or getattr(sys, "dangerzone_dev", False)
@ -367,7 +367,7 @@ class IsolationProvider(ABC):
f"{DOC_TO_PIXELS_LOG_END}" f"{DOC_TO_PIXELS_LOG_END}"
) )
def _stream_stderr(self, stderr, queue: Queue) -> None: def _stream_stderr(self, stderr: IO[bytes], queue: Queue) -> None:
"""Read stderr in a separate thread to avoid blocking""" """Read stderr in a separate thread to avoid blocking"""
try: try:
for line in stderr: for line in stderr:
@ -383,6 +383,6 @@ class IsolationProvider(ABC):
stderr_thread = threading.Thread( stderr_thread = threading.Thread(
target=self._stream_stderr, target=self._stream_stderr,
args=(process.stderr, self.stderr_queue), args=(process.stderr, self.stderr_queue),
daemon=True daemon=True,
) )
stderr_thread.start() stderr_thread.start()

View file

@ -154,7 +154,7 @@ class Container(IsolationProvider):
args, args,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=self.proc_stderr, stderr=subprocess.PIPE,
startupinfo=startupinfo, startupinfo=startupinfo,
# Start the conversion process in a new session, so that we can later on # Start the conversion process in a new session, so that we can later on
# kill the process group, without killing the controlling script. # kill the process group, without killing the controlling script.
@ -192,18 +192,10 @@ class Container(IsolationProvider):
args_str = " ".join(shlex.quote(s) for s in args) args_str = " ".join(shlex.quote(s) for s in args)
log.info("> " + args_str) log.info("> " + args_str)
process = subprocess.Popen( process = self.exec(args)
args, # Start stderr reader thread, attaching it to the process
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, # Always pipe stderr
startupinfo=startupinfo,
start_new_session=True,
)
# Start stderr reader thread
self.start_stderr_thread(process) self.start_stderr_thread(process)
return process return process
def kill_container(self, name: str) -> None: def kill_container(self, name: str) -> None: