In article <200705160759.l4G7x8Tr014065 / sharui.nakada.kanuma.tochigi.jp>,
Nobuyoshi Nakada  <nobu / ruby-lang.org> wrote:
>Hi,
>
>At Wed, 16 May 2007 15:40:08 +0900,
>
>=46rom where is this function called?  Unless it's called as a
>ruby method, you can't use rb_yield() in it.  You might assume
>the block to bmidi_each() is accessible, it is never guaranteed
>at all.
Yes, I realize this now.  [In fact I realized it during my last post,
saw the real solution, started to report that, then started thinking
it was *still* wrong, and erased it!  On the way to bed it dawned on
me it was correct after all.]

I was being fooled a bit by the PickAxe 'jukebox' example, which uses
a callback from external code, but of course he assumes everything is
single-threaded, so that the callback *does* derive from a ruby call
somewhere back up the call chain.
 
>
>
>Since bmidi_ensure() won't get called until bmidi_doeach()
>ends, the latter seems to success to acquire the semaphore only
>when the callback released it.  At that time, the callback sets
>receiving to false before the release, so the bmidi_ensure()
>leaves the semaphore locked which acquired by bmidi_doeach(), I
>guess.  In short, the sequence is wrong.
Actually, no.  I think that part is correct.  The callback only
releases the semaphore *if* the yield signals termination.  The
idea of the ensure was to release the semaphore if the callback hadn't
-- i.e. if break bypassed the yield.
>
>Anyway, you need to call rb_yield() in bmidi_each().
*This* is the key.  I was sort of thinking in the OS's framework,
not Ruby's.  At first I didn't think I could have the yield there,
but I realize that I can rearrange the semaphoring to synchronize
the two (OS) threads, and keep everything nice and orderly.

Thanks for your help
				-- Pete --



-- 
============================================================================
The address in the header is a Spam Bucket -- don't bother replying to it...
(If you do need to email, replace the account name with my true name.)