bader+@andrew.cmu.edu (Miles Bader) (01/09/89)
Will a WaitIO() eat more than one request if they use the same reply port? I'm queueing a bunch of writes to the audio device, then for each one, doing a Wait() on the reply port (so I can detect ^C) and then a WaitIO(). But I always end up having to ^C out of the loop, so it looks like some of my replies are getting eaten. Also, why do DoIO() & SendIO() clear the io_Flags field? It doesn't seem like particularly useful behavior (and if they didn't, you wouldn't need BeginIO). [It took me a while to figure out why my flags were getting ignored...] -Miles
dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (01/09/89)
:Will a WaitIO() eat more than one request if they use the same reply :port? I'm queueing a bunch of writes to the audio device, then for :each one, doing a Wait() on the reply port (so I can detect ^C) and :then a WaitIO(). But I always end up having to ^C out of the loop, so :it looks like some of my replies are getting eaten. : :Also, why do DoIO() & SendIO() clear the io_Flags field? It doesn't :seem like particularly useful behavior (and if they didn't, you :wouldn't need BeginIO). [It took me a while to figure out why my :flags were getting ignored...] : :-Miles No, WaitIO() only removes the specific request you are WaitIO()ing. Your problem is the audio.device. I posted a message just a couple days ago on the bug. The audio.device has a bug in the manner in which it replies IO requests (CMD_WRITEs in particular)... sometimes it appears to be using PutMsg() or equivalent instead of ReplyMsg(). WaitIO() only works with requests that have been replied w/ ReplyMsg(). The way to get around this bug is to WaitPort(replyport) and then GetMsg() the returned requests off instead of WaitIO()ing them. The requests still get replied, just don't get setup properly for WaitIO() to work. DoIO() and SendIO() incorrectly modify ALL the bits in the io_Flags field instead of just IOF_QUICK. Thus, you must use BeginIO() with the audio.device ... if IOF_QUICK is cleared and you call BeginIO(), it is equivalent to SendIO() without modifying the other flag bits: Ioa.ioa_Request.io_Flags = ADIOF_PERVOL; BeginIO(&Ioa); (Normally people want to set the ADIOF_PERVOL flag in the CMD_WRITEs) Finally, doing a Wait() to detect ^C doesn't seem right. Wait() always BLOCKS until one or more of the signals come in. Even if you are also Wait()ing on the reply port's signal it is possible for the audio.device to reply SEVERAL of the requests before your loop gets back to the Wait(). This is ok though because the second while will clear everything that has been returned since the Wait(), and if anything has been returned after that it will set the signal bit again. while (NumRequestsPending) { register struct IoAudio *ioa; mask = Wait(SIGBREAKF_CTRL_C | ReplyPortSigMask); if (mask & SIGBREAKF_CTRL_C) break; while (ioa = GetMsg(ReplyPort)) { /* do whatever */ --NumRequestsPending; } } /* abort any remaining requests */ /* wait for them to be replied */ while (NumRequestsPending) { register struct IoAudio *ioa; WaitPort(ReplyPort); while (ioa = GetMsg(ReplyPort)) { /* do whatever */ --NumRequestsPending; } } -Matt