# Coroutine implementation using Python threads.
#
# Combines ideas from Guido's Generator module, and from the coroutine
# features of Icon and Simula 67.
#
# To run a collection of functions as coroutines, you need to create
# a Coroutine object to control them:
#    co = Coroutine()
# and then 'create' a subsidiary object for each function in the
# collection:
#    cof1 = co.create(f1 [, arg1, arg2, ...]) # [] means optional,
#    cof2 = co.create(f2 [, arg1, arg2, ...]) #... not list
#    cof3 = co.create(f3 [, arg1, arg2, ...])
# etc.  The functions need not be distinct; 'create'ing the same
# function multiple times gives you independent instances of the
# function.
#
# To start the coroutines running, use co.tran on one of the create'd
# functions; e.g., co.tran(cof2).  The routine that first executes
# co.tran is called the "main coroutine".  It's special in several
# respects:  it existed before you created the Coroutine object; if any of
# the create'd coroutines exits (does a return, or suffers an unhandled
# exception), EarlyExit error is raised in the main coroutine; and the
# co.detach() method transfers control directly to the main coroutine
# (you can't use co.tran() for this because the main coroutine doesn't
# have a name ...).
#
# Coroutine objects support these methods:
#
# handle = .create(func [, arg1, arg2, ...])
#    Creates a coroutine for an invocation of func(arg1, arg2, ...),
#    and returns a handle ("name") for the coroutine so created.  The
#    handle can be used as the target in a subsequent .tran().
#
# .tran(target, data=None)
#    Transfer control to the create'd coroutine "target", optionally
#    passing it an arbitrary piece of data. To the coroutine A that does
#    the .tran, .tran acts like an ordinary function call:  another
#    coroutine B can .tran back to it later, and if it does A's .tran
#    returns the 'data' argument passed to B's tran.  E.g.,
#
#    in coroutine coA   in coroutine coC    in coroutine coB
#      x = co.tran(coC)   co.tran(coB)        co.tran(coA,12)
#      print x # 12
#
#    The data-passing feature is taken from Icon, and greatly cuts
#    the need to use global variables for inter-coroutine communication.
#
# .back( data=None )
#    The same as .tran(invoker, data=None), where 'invoker' is the
#    coroutine that most recently .tran'ed control to the coroutine
#    doing the .back.  This is akin to Icon's "&source".
#
# .detach( data=None )
#    The same as .tran(main, data=None), where 'main' is the
#    (unnameable!) coroutine that started it all.  'main' has all the
#    rights of any other coroutine:  upon receiving control, it can
#    .tran to an arbitrary coroutine of its choosing, go .back to
#    the .detach'er, or .kill the whole thing.
#
# .kill()
#    Destroy all the coroutines, and return control to the main
#    coroutine.  None of the create'ed coroutines can be resumed after a
#    .kill().  An EarlyExit exception does a .kill() automatically.  It's
#    a good idea to .kill() coroutines you're done with, since the
#    current implementation consumes a thread for each coroutine that
#    may be resumed.

import thread
import sync

class _CoEvent:
    def __init__(self, func):
        self.f = func
        self.e = sync.event()

    def __repr__(self):
        if self.f is None:
            return 'main coroutine'
        else:
            return 'coroutine for func ' + self.f.func_name

    def __hash__(self):
        return id(self)

    def __cmp__(x,y):
        return cmp(id(x), id(y))

    def resume(self):
        self.e.post()

    def wait(self):
        self.e.wait()
        self.e.clear()

Killed = 'Coroutine.Killed'
EarlyExit = 'Coroutine.EarlyExit'

class Coroutine:
    def __init__(self):
        self.active = self.main = _CoEvent(None)
        self.invokedby = {self.main: None}
        self.killed = 0
        self.value  = None
        self.terminated_by = None

    def create(self, func, *args):
        me = _CoEvent(func)
        self.invokedby[me] = None
        thread.start_new_thread(self._start, (me,) + args)
        return me

    def _start(self, me, *args):
        me.wait()
        if not self.killed:
            try:
                try:
                    apply(me.f, args)
                except Killed:
                    pass
            finally:
                if not self.killed:
                    self.terminated_by = me
                    self.kill()

    def kill(self):
        if self.killed:
            raise TypeError, 'kill() called on dead coroutines'
        self.killed = 1
        for coroutine in self.invokedby.keys():
            coroutine.resume()

    def back(self, data=None):
        return self.tran( self.invokedby[self.active], data )

    def detach(self, data=None):
        return self.tran( self.main, data )

    def tran(self, target, data=None):
        if not self.invokedby.has_key(target):
            raise TypeError, '.tran target ' + `target` + \
                             ' is not an active coroutine'
        if self.killed:
            raise TypeError, '.tran target ' + `target` + ' is killed'
        self.value = data
        me = self.active
        self.invokedby[target] = me
        self.active = target
        target.resume()

        me.wait()
        if self.killed:
            if self.main is not me:
                raise Killed
            if self.terminated_by is not None:
                raise EarlyExit, `self.terminated_by` + ' terminated early'

        return self.value

# end of module
