Skip to content

Commit

Permalink
Fix regression in 2.10 that caused printing to stdout/stderr in FileT…
Browse files Browse the repository at this point in the history
…ype plugins to not work when running using calibre-debug -g in a windows console
  • Loading branch information
kovidgoyal committed Nov 20, 2014
1 parent 38fe10d commit c356e09
Showing 1 changed file with 46 additions and 4 deletions.
50 changes: 46 additions & 4 deletions src/calibre/utils/ipc/pool.py
Expand Up @@ -12,7 +12,7 @@
from Queue import Queue

from calibre import detect_ncpus, as_unicode, prints
from calibre.constants import iswindows
from calibre.constants import iswindows, DEBUG
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils import join_with_timeout
from calibre.utils.ipc import eintr_retry_call
Expand All @@ -26,9 +26,28 @@
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
get_stdout_from_child = False

if iswindows:
# The windows console cannot show output from child processes
# created with CREATE_NO_WINDOW, so the stdout/stderr file handles
# the child process inherits will be broken. Similarly, windows GUI apps
# have no usable stdout/stderr file handles. In both these cases, redirect
# the child's stdout/stderr to NUL. If we are running in calibre-debug -g,
# then redirect to PIPE and read from PIPE and print to our stdout.
# Note that when running via the "Restart in debug mode" action, stdout is
# not a console (its already redirected to a log file), so no redirection
# is required.
if getattr(sys, 'gui_app', False) or getattr(sys.stdout, 'isatty', lambda : False)():
if DEBUG:
# We are running in a windows console with calibre-debug -g
import subprocess
get_stdout_from_child = True
worker_kwargs['stdout'] = subprocess.PIPE
worker_kwargs['stderr'] = subprocess.STDOUT
else:
from calibre.utils.ipc.launch import windows_null_file
worker_kwargs['stdout'] = worker_kwargs['stderr'] = windows_null_file

class Failure(Exception):

Expand All @@ -44,6 +63,10 @@ def __init__(self, p, conn, events, name):
self.process, self.conn = p, conn
self.events = events
self.name = name or ''
if get_stdout_from_child:
t = Thread(target=self.get_stdout, name='PoolWorkerGetOutput-'+self.name)
t.daemon = True
t.start()

def __call__(self, job):
eintr_retry_call(self.conn.send_bytes, cPickle.dumps(job, -1))
Expand All @@ -66,6 +89,22 @@ def recv(self):
def set_common_data(self, data):
eintr_retry_call(self.conn.send_bytes, data)

def get_stdout(self):
import time
while self.process.poll() is None:
try:
raw = self.process.stdout.read(1)
if raw:
try:
sys.stdout.write(raw)
except EnvironmentError:
pass
else:
time.sleep(0.1)
except (EOFError, EnvironmentError):
break


class Pool(Thread):

daemon = True
Expand Down Expand Up @@ -339,6 +378,9 @@ def run_main(func):
with closing(Client(address, authkey=key)) as conn:
raise SystemExit(func(conn))

def test_write():
print ('Printing to stdout in worker')

def test():
def get_results(pool, ignore_fail=False):
ans = {}
Expand Down

0 comments on commit c356e09

Please sign in to comment.