#!/usr/bin/env python
from concurrent.futures import wait, ThreadPoolExecutor, FIRST_COMPLETED
from subprocess import Popen, PIPE
from sys import argv
def interact (player, solution, kill_player=False, kill_solution=True):
player = Popen(player, stdin=PIPE, stdout=PIPE)
solution = Popen(solution, stdin=player.stdout, stdout=player.stdin)
try:
executor = ThreadPoolExecutor(max_workers=2)
futures = [executor.submit(x.wait) for x in (player, solution)]
wait(futures, return_when=FIRST_COMPLETED)
if kill_player and solution.returncode is not None:
player.terminate()
assert {solution.returncode} <= {0, None}
elif kill_solution and player.returncode is not None:
solution.terminate()
assert {player.returncode} <= {0, None}
else:
assert {player.returncode, solution.returncode} <= {0, None}
wait(futures)
assert {player.returncode, solution.returncode} <= {0, None}
finally:
player.kill()
solution.kill()
if __name__ == '__main__':
interact(argv[1], argv[2])