diff --git a/src/calibre/utils/ipc/launch.py b/src/calibre/utils/ipc/launch.py index eb020e7222..2302d9bf9e 100644 --- a/src/calibre/utils/ipc/launch.py +++ b/src/calibre/utils/ipc/launch.py @@ -187,9 +187,19 @@ class Worker: args['stderr'] = subprocess.STDOUT args['close_fds'] = True - if pass_fds: - args['pass_fds'] = pass_fds - self.child = subprocess.Popen(cmd, **args) + try: + if pass_fds: + if iswindows: + for fd in pass_fds: + os.set_handle_inheritable(fd, True) + args['startupinfo'] = subprocess.STARTUPINFO(lpAttributeList={'handle_list':pass_fds}) + else: + args['pass_fds'] = pass_fds + self.child = subprocess.Popen(cmd, **args) + finally: + if iswindows and pass_fds: + for fd in pass_fds: + os.set_handle_inheritable(fd, False) if 'stdin' in args: self.child.stdin.close() diff --git a/src/calibre/utils/ipc/pool.py b/src/calibre/utils/ipc/pool.py index 8a7a4265b4..d88148a8f1 100644 --- a/src/calibre/utils/ipc/pool.py +++ b/src/calibre/utils/ipc/pool.py @@ -387,7 +387,10 @@ def worker_main(conn): def run_main(client_fd, func): - from multiprocessing.connection import Connection + if iswindows: + from multiprocessing.connection import PipeConnection as Connection + else: + from multiprocessing.connection import Connection with Connection(client_fd) as conn: raise SystemExit(func(conn)) diff --git a/src/calibre/utils/ipc/simple_worker.py b/src/calibre/utils/ipc/simple_worker.py index fc0af076ae..7710cdb268 100644 --- a/src/calibre/utils/ipc/simple_worker.py +++ b/src/calibre/utils/ipc/simple_worker.py @@ -146,19 +146,30 @@ def start_pipe_worker(command, env=None, priority='normal', **process_args): w = Worker(env or {}) args = {'stdout':subprocess.PIPE, 'stdin':subprocess.PIPE, 'env':w.env, 'close_fds': True} args.update(process_args) - if iswindows: - priority = { - 'high' : subprocess.HIGH_PRIORITY_CLASS, - 'normal' : subprocess.NORMAL_PRIORITY_CLASS, - 'low' : subprocess.IDLE_PRIORITY_CLASS}[priority] - args['creationflags'] = subprocess.CREATE_NO_WINDOW|priority - else: - niceness = {'normal' : 0, 'low' : 10, 'high' : 20}[priority] - args['env']['CALIBRE_WORKER_NICENESS'] = str(niceness) + pass_fds = None + try: + if iswindows: + priority = { + 'high' : subprocess.HIGH_PRIORITY_CLASS, + 'normal' : subprocess.NORMAL_PRIORITY_CLASS, + 'low' : subprocess.IDLE_PRIORITY_CLASS}[priority] + args['creationflags'] = subprocess.CREATE_NO_WINDOW|priority + pass_fds = args.pop('pass_fds', None) + if pass_fds: + for fd in pass_fds: + os.set_handle_inheritable(fd, True) + args['startupinfo'] = subprocess.STARTUPINFO(lpAttributeList={'handle_list':pass_fds}) + else: + niceness = {'normal' : 0, 'low' : 10, 'high' : 20}[priority] + args['env']['CALIBRE_WORKER_NICENESS'] = str(niceness) - exe = w.executable - cmd = [exe] if isinstance(exe, string_or_bytes) else exe - p = subprocess.Popen(cmd + ['--pipe-worker', command], **args) + exe = w.executable + cmd = [exe] if isinstance(exe, string_or_bytes) else exe + p = subprocess.Popen(cmd + ['--pipe-worker', command], **args) + finally: + if iswindows and pass_fds: + for fd in pass_fds: + os.set_handle_inheritable(fd, False) return p diff --git a/src/calibre/utils/ipc/worker.py b/src/calibre/utils/ipc/worker.py index 389e582374..445f14d992 100644 --- a/src/calibre/utils/ipc/worker.py +++ b/src/calibre/utils/ipc/worker.py @@ -6,17 +6,23 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, sys, importlib -from multiprocessing.connection import Connection +import importlib +import os +import sys from threading import Thread from zipimport import ZipImportError from calibre import prints -from calibre.constants import iswindows, ismacos +from calibre.constants import ismacos, iswindows from calibre.utils.ipc import eintr_retry_call from calibre.utils.serialize import pickle_dumps -from polyglot.queue import Queue from polyglot.binary import from_hex_unicode +from polyglot.queue import Queue + +if iswindows: + from multiprocessing.connection import PipeConnection as Connection +else: + from multiprocessing.connection import Connection PARALLEL_FUNCS = { 'lrfviewer' :