#!/usr/bin/env python

import threading, subprocess, sys, signal
import Queue

# Except a thread count as the single argument.
maxthreads = int(sys.argv[1])
print "Using %d threads\n" % maxthreads

# This is to try to get everyone to quit when CTRL-C is pressed.
quit_is_true = False

# Create the queues that we use for work and for output.
q_work = Queue.Queue(maxthreads)
q_result = Queue.Queue(maxthreads*2)

def process(workk):
  return subprocess.check_output(workk, shell=True)

def worker():
  global quit_is_true
  while True:
    mywork = q_work.get()
    if mywork is None or quit_is_true:
      return
    try:
      q_result.put("# %s\n%s\n%s%s" % (
        mywork, ">" * 10, process(mywork), "<" * 10))
    except: # This is what happens when CTRL-C is pressed.
      quit_is_true = True

def worker2():
  while True:
    mywork = q_result.get()
    if mywork is None:
      return
    print mywork

threads = [ threading.Thread(target=worker) for _i in range(maxthreads) ]
threads2 = threading.Thread(target=worker2)

def quit():
  # One None for each thread.
  for thread in threads:
    q_work.put(None)

  # Wait for all the threads to quit.
  for thread in threads:
    thread.join()

  # And a None for the output thread.
  q_result.put(None)

def signal_handler(sig, frame):
  global quit_is_true
  quit_is_true = True
  quit()
  sys.exit(1)

signal.signal(signal.SIGINT, signal_handler)

for thread in threads:
  thread.start()
threads2.start()

# Do some work for each line in stdin.
for line in sys.stdin:
  line = line.strip()
  q_work.put(line)

quit()
