[email protected] wrote:
On Mon, Jan 25, 2010 at 03:34:00PM -0600, Shawn Walker wrote:
As for the generator bit, if the wrapper function does something like:
try:
return self.__generator_func()
except ...:
...
finally:
....
...it will be fine. There's no real difference between returning a
generator (as shown above) or calling the generator directly.
I might still be missing something here though.
Is this going to work properly with locking, though?
If __generator_func() needs to hold a lock as long as it is returning
results, won't releasing the lock in the finally statement cause the
lock to get dropped after the generator is returned to the caller?
That's not what's desired, I think, since we want the lock held while
the generator is running.
This also raises another interesting question about holding locks in
these functions: if the caller never runs the generator to completion,
at what point does python destroy the generator object? What happens to
the locks that are held? Does this mean that we need to drop and
re-acquire any locks around a yield statment? (I'm guessing the
answer is yes.)
If the answer is yes, we don't really want to drop and re-acquire the
activity lock, and disable/enable cancel every time this function
yields.
I think this means we really want to do something like:
def remote_search_wrapper():
activity_lock.acquire()
enable_cancel()
try:
r = remote_search()
while r:
yield r
finally:
disable_cancel()
activity_lock.release()
However, I don't know whether this will cause all of remote_search()'s
results to be held in memory, or if this will just return True as long
as the function still has results to return. Is this documented
anywhere?
[snip]
To help me understand what was going on, I created the attached python
program. Here's the output when I run it:
running
k:4
Got to finally, i:1
calling but not iterating
after calling but not iterating
k2:3
Got to finally, i:0
My interpretation is that:
a) The lock will not be taken until the first attempt to iterate across
the results is made. This shouldn't be a problem unless the caller does
something like, a= remote_search(), then starts another thread which
grabs the activity lock, then starts attempting to iterate over a. I
think this is reasonably classified as "don't do that."
b) The question of what to do if the caller doesn't run to completion is
interesting, and I don't have a good answer.
Your wrapper has the same semantics (I think) as putting the try/finally
inside remote_search. What you have shouldn't cause the results to be
held in memory, and it has the same problem with callers that don't run
till completion.
_______________________________________________
pkg-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/pkg-discuss