Turning f(callback) into a generator

Jeff Epler jepler at unpythonic.net
Fri Dec 5 15:15:39 EST 2003


On Fri, Dec 05, 2003 at 07:42:22PM +0100, Peter Otten wrote:
> How do you handle the case where the generator is not run to exhaustion?

I didn't think about it or see your other message before I posted my code.

I suppose you'd have to add some sort of communication in the opposite
direction that causes cb to raise an exception instead of putting
something in the queue.  Something like:

    def delete(self):
        self.queue = None

    def __del__(self):
        if self.queue is not None: self.delete()

    def cb(self):
        if self.queue is None: raise AppropriateException
        ...

    def go(self):
        try:
            ...
        except AppropriateException:
            return # exit thread

but this isn't quite right because delete must deal with a previous cb
that is blocked, as well as races between 'delete' changing queue and cb
using it.

What you'd really want is a Queue subclass with a .shutdown() method:
after a queue has been shutdown, any put() (including a blocked put in
another thread) fails immediately with an exception, and get() (including
a blocked get in another thread) fails immediately if the queue is empty.

... and __del__ still won't work because there are live references to
self in the callback-thread.  You'll need a container class that the
thread doesn't reference whose __del__ takes care of doing the queue
shutdown.

Jeff





More information about the Python-list mailing list