On Mon, 2008-10-06 at 20:42 +0200, Hans Meine wrote: > Now that I read it again, let me try to understand it:
Dischi explained much of this, but let me be a bit more pedantic and dissect some of your statements: > yield kaa.beacon.query will actually suspend the surrounding function > (coroutine), Not contradicting what you said here, but an as aside, coroutines can terminate immediately, just like any other function. But they do always return InProgress objects. @kaa.coroutine() def immediate(): yield 42 @kaa.coroutine() def delayed(): yield kaa.NotFinished yield 42 assert(immediate().finished == True) assert(delayed().finished == False) Now, let's suppose that delayed() yields immediate() instead of kaa.NotFinished. Is delayed().finished == False? No, it actually finishes immediately now. Because it yields a finished InProgress (immediate()), it is reentered immediately (by the wrapper code in the kaa.coroutine decorator) and does not wait for the next main loop iteration. > which is possible only because this is in a main() function decorated > as coroutine, Right, if main() was not decorated as a coroutine then it would not be reentered. > and this actually runs from kaa.main.run(), It probably does, yes. It would only get reentered via the mainloop iff kaa.beacon.query() returned an _un_finished InProgress, as per my explanation above. Incidentally, when I say "reentered" I just mean that the generator's next() method is called. Coroutines decorate functions that yield values, which means coroutines decorate generators. Coroutine's simply facilitate scheduling how and when that generator's next() will be called. > so the yield will yield an InProgress object returned by beacon.query > to the main loop, which will resume the coroutine using python 2.5's > new send() method, It's worth digging in a bit deeper here, and removing some ambiguity: 1. Assuming beacon.query() returned an unfinished InProgress, the next() method of query()'s underlying generator would be scheduled at the next mainloop step. 2. This generator's next() would be called until it yields a non-InProgress object or it raises StopIteration (which means we reached the end of the generator without any return value), or if next() raises some other exception, and then the InProgress is finished with error. Then query()'s InProgress is finished and: A. If query()'s generator did not raise an exception, the query() coroutine's InProgress result is passed into main()'s generator via Python 2.5's send() method of the generator. This allows the yield kaa.beacon.query(...) expression to return a value. send() implicitly resumes the generator. (It's like calling next(), only the yield returns a value.); or, B. If query()'s InProgress is finished with exception, then the throw() method of main()'s generator is called, causing the yield kaa.beacon.query(...) expression to raise an exception. With Python 2.4, we don't have send() or throw() methods of generators. So we would need to do something like this instead: ip = kaa.beacon.query(...) yield ip for m in ip.result: ... If the InProgress was finished with an exception, accessing ip.result will cause that exception to raise. Hopefully this helps clarify the magic of kaa.coroutine a bit better. :) Jason. ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Freevo-devel mailing list Freevo-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freevo-devel