Make "git command" and "forall" work on Windows

Python on Windows does not support non blocking file operations.
To workaround this issue, we instead use Threads and a Queue to
simulate non-blocking calls. This is happens only when running
with the native Windows version of Python, meaning Linux and Cygwin
are not affected by this change.

Change-Id: I4ce23827b096c5138f67a85c721f58a12279bb6f
This commit is contained in:
Renaud Paquay
2016-11-01 11:23:38 -07:00
committed by David Pursehouse
parent 35d22217a5
commit 2e70291162
3 changed files with 186 additions and 41 deletions

View File

@ -15,17 +15,16 @@
from __future__ import print_function
import errno
import fcntl
import multiprocessing
import re
import os
import select
import signal
import sys
import subprocess
from color import Coloring
from command import Command, MirrorSafeCommand
import platform_utils
_CAN_COLOR = [
'branch',
@ -344,35 +343,25 @@ def DoWork(project, mirror, opt, cmd, shell, cnt, config):
if opt.project_header:
out = ForallColoring(config)
out.redirect(sys.stdout)
class sfd(object):
def __init__(self, fd, dest):
self.fd = fd
self.dest = dest
def fileno(self):
return self.fd.fileno()
empty = True
errbuf = ''
p.stdin.close()
s_in = [sfd(p.stdout, sys.stdout),
sfd(p.stderr, sys.stderr)]
s_in = platform_utils.FileDescriptorStreams.create()
s_in.add(p.stdout, sys.stdout, 'stdout')
s_in.add(p.stderr, sys.stderr, 'stderr')
for s in s_in:
flags = fcntl.fcntl(s.fd, fcntl.F_GETFL)
fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
while s_in:
in_ready, _out_ready, _err_ready = select.select(s_in, [], [])
while not s_in.is_done:
in_ready = s_in.select()
for s in in_ready:
buf = s.fd.read(4096)
buf = s.read()
if not buf:
s.fd.close()
s.close()
s_in.remove(s)
continue
if not opt.verbose:
if s.fd != p.stdout:
if s.std_name == 'stderr':
errbuf += buf
continue