Fix writing to stdout/stderr in pool worker processes on windows not working

This commit is contained in:
Kovid Goyal 2014-11-13 09:36:46 +05:30
parent ad6405c573
commit a7899be02d
2 changed files with 9 additions and 3 deletions

View File

@ -16,7 +16,7 @@ from calibre.ptempfile import PersistentTemporaryFile, base_dir
if iswindows: if iswindows:
import win32process import win32process
try: try:
_windows_null_file = open(os.devnull, 'wb') windows_null_file = open(os.devnull, 'wb')
except: except:
raise RuntimeError('NUL file missing in windows. This indicates a' raise RuntimeError('NUL file missing in windows. This indicates a'
' corrupted windows. You should contact Microsoft' ' corrupted windows. You should contact Microsoft'
@ -212,7 +212,7 @@ class Worker(object):
# On windows when using the pythonw interpreter, # On windows when using the pythonw interpreter,
# stdout, stderr and stdin may not be valid # stdout, stderr and stdin may not be valid
args['stdin'] = subprocess.PIPE args['stdin'] = subprocess.PIPE
args['stdout'] = _windows_null_file args['stdout'] = windows_null_file
args['stderr'] = subprocess.STDOUT args['stderr'] = subprocess.STDOUT
if not iswindows: if not iswindows:

View File

@ -12,6 +12,7 @@ from collections import namedtuple
from Queue import Queue from Queue import Queue
from calibre import detect_ncpus, as_unicode, prints from calibre import detect_ncpus, as_unicode, prints
from calibre.constants import iswindows
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils import join_with_timeout from calibre.utils import join_with_timeout
from calibre.utils.ipc import eintr_retry_call from calibre.utils.ipc import eintr_retry_call
@ -24,6 +25,11 @@ File = namedtuple('File', 'name')
MAX_SIZE = 30 * 1024 * 1024 # max size of data to send over the connection (old versions of windows cannot handle arbitrary data lengths) MAX_SIZE = 30 * 1024 * 1024 # max size of data to send over the connection (old versions of windows cannot handle arbitrary data lengths)
worker_kwargs = {'stdout':None}
if iswindows and getattr(sys, 'gui_app', False):
from calibre.utils.ipc.launch import windows_null_file
worker_kwargs['stdout'] = worker_kwargs['stderr'] = windows_null_file
class Failure(Exception): class Failure(Exception):
def __init__(self, tf): def __init__(self, tf):
@ -132,7 +138,7 @@ class Pool(Thread):
def create_worker(self): def create_worker(self):
from calibre.utils.ipc.simple_worker import start_pipe_worker from calibre.utils.ipc.simple_worker import start_pipe_worker
p = start_pipe_worker( p = start_pipe_worker(
'from {0} import run_main, {1}; run_main({1})'.format(self.__class__.__module__, 'worker_main'), stdout=None) 'from {0} import run_main, {1}; run_main({1})'.format(self.__class__.__module__, 'worker_main'), **worker_kwargs)
sys.stdout.flush() sys.stdout.flush()
eintr_retry_call(p.stdin.write, self.worker_data) eintr_retry_call(p.stdin.write, self.worker_data)
p.stdin.flush(), p.stdin.close() p.stdin.flush(), p.stdin.close()