[comp.sys.amiga.tech] AbortIO with Timer device

lindwall@sdsu.UUCP (John Lindwall) (12/24/88)

Background
----------

	I am writing a program which is using the timer device to act as a
(surprise) timer.  It is a quiz program on the International System of Units.
I want to time the user while he takes the quiz.  The user's score will be based
on # of correct answers, # of wrong guesses, and the amount of time it took.  I
want to display a timer in the (WorkBench) window which increments every second.

	I can set up stuff properly to get timer events every second.  I am
using the UNIT_VBLANK timer.  Fine accuracy is not super important.  So far
all is fine.

Problems with AbortIO()
-----------------------

	My problem is that sometimes I wish to abort the current timer request.
After aborting the current request (and going off to do other stuff) I need the
timing to resume.  I am currently re-using the same timerequest and calling
(as before) SendIO() to request a timer event.  The timer never sends another
event!

	Does AbortIO() have an adverse effect on my communications to the timer
device?  I've tried re-opening the device with OpenDevice() but it doesn't help.
Do I have to open a new Port to the timer device with CreatePort()?

Please Help me!				Thanks, John Lindwall
---------------

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (12/25/88)

>
>	Does AbortIO() have an adverse effect on my communications to the timer
>device?  I've tried re-opening the device with OpenDevice() but it doesn't help.
>Do I have to open a new Port to the timer device with CreatePort()?

	AbortIO() causes the request to be returned to the message port but
not removed.  Furthermore,  AbortIO() is an advisory call to the device and
device will not abort if it cannot abort (the timer.device is able to abort
any active request so you don't have to worry about that).  Thus, the
proper 'abort' sequence is:

	AbortIO(timreq); /* request timer.device to abort it	*/
	WaitIO(timreq);	/* wait for it to be returned & remove it from the
			 * reply port
			 */

	Note also that the timer.device DESTROYS the time fields of the
request... To restart any request, even if it came back normally, you must
reload the fields:

	timreq->tr_time.tv_secs  = <blah>;
	timreq->tr_time.tv_micro = <blah>;
	SendIO(timreq);

		...

	Also remember that receiving a signal from the replyport does not
guarentee the request has been returned, always CheckIO() the request (unless
you are using the replyport to sink several requests and thus using GetMsg()).

	Mask = Wait(signals...)
	/* note: probably want to cache the signal bit# or mask for timreq */
	if (Mask & (1 << timreq->tr_node.io_Message.mn_ReplyPort->mp_SigBit)) {
	    if (CheckIO(timreq) {		/* request returned?*/
		WaitIO(timreq);			/* remove from repport */
		puts("SURPRISE!");
		timreq->tr_time.tv_secs  = <blah>;	/* restart */
		timreq->tr_time.tv_micro = <blah>;
		SendIO(timreq);
	    }
	}

				-Matt