[comp.sys.amiga.tech] io questions

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