@@ -0,0 +1,2696 @@
+# encoding: UTF-8%0A%0A%22%22%22%0AUtilities and extensions for the %60cothread%60_ library.%0A%0A.. cothread: http://controls.diamond.ac.uk/downloads/python/cothread%0A%0A.. moduleauthor:: Dylan Maxwell %3Cmaxwelld@frib.msu.edu%3E%0A%22%22%22%0A%0Afrom __future__ import division%0Afrom __future__ import print_function%0Afrom __future__ import absolute_import%0Afrom __future__ import unicode_literals%0A%0Aimport subprocess%0Aimport threading%0A%0Aimport cothread%0A%0A%0Aclass Popen(object):%0A    %22%22%22%0A    Utility for integrating the standard Python Popen class with%0A    the cothread library's synchronization primitives. The API is%0A    designed to be the same of the standard Popen.%0A    %22%22%22%0A    def __init__(self, *args, **kwargs):%0A        %22%22%22%0A        Initialize the Popen class by creating a new subprocess.%0A%0A        All arguments are passed unaltered to the underlying subprocess%0A        %60Popen%60_ constructor%0A%0A        .. Popen: https://docs.python.org/2/library/subprocess.html#popen-constructor%0A        %22%22%22%0A        self._process = subprocess.Popen(*args, **kwargs)%0A        self._output = None%0A        self._event = None%0A%0A%0A    def communicate(self, input=None):%0A        %22%22%22Start a real OS thread to wait for process communication.%0A        %22%22%22%0A        # To manintain compatibility with the standard library%0A        # the 'input' keyword argument is used which redefines%0A        # the builtin function.%0A        #   pylint: disable=redefined-builtin%0A        if self._event is None:%0A            self._event = cothread.Event()%0A            threading.Thread(target=self._communicate_thread,%0A                             args=(input,)).start()%0A        elif input is not None:%0A            raise RuntimeError(%22Popen: Communicate method already called%22)%0A        self._event.Wait()%0A        return (self._output%5B0%5D, self._output%5B1%5D, self._process.poll())%0A%0A%0A    def _communicate_thread(self, input_):%0A        %22%22%22Executes in separate OS thread. Wait for communication%0A           then return the output to the cothread context.%0A        %22%22%22%0A        output = self._process.communicate(input_)%0A        cothread.Callback(self._communicate_callback, output)%0A%0A%0A    def _communicate_callback(self, output):%0A        %22%22%22Record the output and then signal other cothreads.%0A        %22%22%22%0A        self._output = output%0A        self._event.Signal()%0A%0A%0A    def wait(self):%0A        %22%22%22Wait for the process to complete and result the exit code.%0A        %22%22%22%0A        self.communicate()%0A        return self._process.poll()%0A%0A%0A    def terminate(self):%0A        %22%22%22Send the terminate signal. See subprocess.Popen.terminate()%0A        %22%22%22%0A        self._process.terminate()%0A%0A%0A    def kill(self):%0A        %22%22%22Send the kill signal.  See subprocess.Popen.kill()%0A        %22%22%22%0A        self._process.kill()%0A

Add utility class integrates the standard Popen class with cothread library.