[comp.sys.amiga.tech] Aborting TimerReq

dlarson@blake.acs.washington.edu (Dale Larson) (11/18/89)

/*  eat this? */

A few weeks ago, I posted a message about a problem with aborting a
timer request.  The only response I recieved indicated that doing
so is not possible.  I have found a kludgy way of aborting the request, 
and would like to know why it seems to be necessary.  If I'd saved that
address for sending bug reports to, I'd send it.
 
From: lsuc!nrcaer!julie!mcr@neat.ai.toronto.edu (Michael Richardson)
>>Is the only way to reuse my timer request to close down the device and port
>>and re-open them???  Or have I (HOPEFULLY!) done something stupid again?
>  Look at the entry for timer.device again --- notice the lack of support
>for AbortIO()?
>  You can't abort the timer.device.
>  Everyone seems to anyway though... and it worked for me, until a friend
>pointed out that you can't abort it.

Page B-68 of the printed 1.3 AutoDocs (the entry for 
timer.device/TR_ADDREQUEST) says:

"The message may be forced to finish early with an AbortIO()/WaitIO()
pair."

As stated in my original message (to which I have recieved no other replies)
I cannot get things to work properly with a simple AbortIO()/WaitIO() pair.
The WaitIO() always returns error IOERR_ABORTED (or whatever) and fails
to clear some bit or another.  The following code segment, however, has 
been working for me:

			if(AbortIO((struct IORequest *)TimerReq))
			{
				close_down("AbortIO(TimerReq) Error!");
			}
			if(error=WaitIO((struct IORequest *)TimerReq))
			{
				Wait(1<<TimerPort->mp_SigBit);
			}

If I replace the WaitIO() with the Wait(), however, something else is broken
(it waits forever if I recall correctly, it's been a few weeks and my notes
are jumbled).

Can anyone shed any light for me?

-- 
	    A lack of prior planning on the part of any programmer 
		       always constitutes an emergency.
	
           Digital Teddy Bear      dlarson@blake.acs.washington.edu

kodiak@amiga.UUCP (Robert R. Burns) (11/22/89)

In article ... dlarson@blake.acs.washington.edu (Dale Larson) writes:
)Page B-68 of the printed 1.3 AutoDocs (the entry for
)timer.device/TR_ADDREQUEST) says:
)
)"The message may be forced to finish early with an AbortIO()/WaitIO() pair."

I abort TR_ADDREQUEST requests as follows (here follows C version of asm
code used to abort the time request that causes keys to repeat in the
input device task):

	AbortIO(TimerReq);
	WaitIO(TimerReq);

Notes:
    1.  the result of AbortIO is always meaningless.  For example, if
	the timer has already handled the TR_ADDREQUEST, it would
	report that the AbortIO failed -- but you don't care because
	you're doing a WaitIO next anyway.
    2.  the result of WaitIO is meaningless here.  What do you care whether
	the timer request was satisfied or aborted: your code flow is
	only interested in retrieving the TimerReq for reuse, which it
	has done successfully at this point.

[he then describes some problems and his solution]

)The WaitIO() always returns error IOERR_ABORTED (or whatever) and fails
)to clear some bit or another.

I don't know what bit you're talking about.
-- 
Bob Burns, amiga!kodiak						 _
	| /_  _|. _ |		   Commodore __			|_) _ |_  _ )'
	|<(_)(_)|(_\|<		    /\ |  ||| _` /\		|_)(_\| )(_\ |
	| \ Software		___/..\|\/|||__|/..\___			 Faith

usenet@cps3xx.UUCP (Usenet file owner) (11/24/89)

In article <4883@amiga.UUCP> kodiak@batgirl.UUCP (Robert R. Burns) writes:
>In article ... dlarson@blake.acs.washington.edu (Dale Larson) writes:
>input device task):
>
>	AbortIO(TimerReq);
>	WaitIO(TimerReq);

A related question: In general (any specifics please) is the following
sequence of calls valid:
	
		p = CreateExtIO(myport, sizeof(*p));

		OpenDevice(device.name , 0, p, flags);

	/* Note that there are *no* SendIO(p) or DoIO(p) calls here */
		AbortIO(p)
		WaitIO(p);

		/* Finish clean up here */

The only thing that I think may have problems is the WaitIO(p) call.
Would it?
 Joe Porkka   porkka@frith.egr.msu.edu

mcr@julie.UUCP (Michael Richardson) (11/25/89)

In some message which my not quite real news software doesn't know how
to reply to, Dale Larson wrote:
>A few weeks ago, I posted a message about a problem with aborting a
>timer request.  The only response I recieved indicated that doing
>so is not possible.  I have found a kludgy way of aborting the request,
>and would like to know why it seems to be necessary.  If I'd saved that
>address for sending bug reports to, I'd send it.

>From: lsuc!nrcaer!julie!mcr@neat.ai.toronto.edu (Michael Richardson)
>>>Is the only way to reuse my timer request to close down the device and port
>>>and re-open them???  Or have I (HOPEFULLY!) done something stupid again?
>>  Look at the entry for timer.device again --- notice the lack of support
>>for AbortIO()?
>>  You can't abort the timer.device.
>>  Everyone seems to anyway though... and it worked for me, until a friend
>>pointed out that you can't abort it.

  Well --- the edition of the RKM and autodocs that I had was 1.2. It
makes no mention of AbortIO() on a timer.device request. It seems that
the 1.3 manuals do make mention...

>As stated in my original message (to which I have recieved no other replies)
>I cannot get things to work properly with a simple AbortIO()/WaitIO() pair.
>The WaitIO() always returns error IOERR_ABORTED (or whatever) and fails

  Hmm. Some my problems with it might have stemmed from the fact
that I wasn't always WaitIO()ing my aborted requests... This seems to
have cleaned up some of my problems, but it is possible that there are
still other problems caused by whatever it is that you are seeing...

>to clear some bit or another.  The following code segment, however, has
>been working for me:
  [code that Wait()s after the WaitIO() removed]

>If I replace the WaitIO() with the Wait(), however, something else is broken
>(it waits forever if I recall correctly, it's been a few weeks and my notes
>are jumbled).

  Hmm. I believe that WaitIO() doesn't call Wait() if the request has
already arrived. I would expect that it checks the ln_Node member for
NT_REPLY, and if found Remove()s the entry from whatever message queue
it is on. If not it Wait()s for the signal, and does the check again.
Why a Wait() _after_ the WaitIO() request doesn't block, I'm not sure...
But I can see that if the message has already arrived, replacing WaitIO()
might not work correctly....



--

  :!mcr!:
  Michael Richardson
                    Amiga
             v--------+
 HOME: mcr@julie.UUCP | SCHOOL: mcr@doe.carleton.ca
 Fido: 1:163/109.10<--+ WORK: michael@fts1.UUCP

ridder@elvira.enet.dec.com (Hans Ridder) (11/26/89)

In article <1498.AA1498@julie> mcr@julie.UUCP (Michael Richardson) writes:
>  Hmm. I believe that WaitIO() doesn't call Wait() if the request has
>already arrived. I would expect that it checks the ln_Node member for
>NT_REPLY, and if found Remove()s the entry from whatever message queue
>it is on. If not it Wait()s for the signal, and does the check again.

That is basically correct, WaitIO() doesn't call Wait() unless the
IOF_QUICK bit is clear *and* the node type is *other than* NT_REPLY.

The IOF_QUICK bit indicates that the request was completed quickly,
and thus the device did not do a ReplyMsg().  The node type NT_REPLY
indicates that the request was *not* completed quickly, but the device
has completed it, and used ReplyMsg() to send it back to you.  Either
way, the request is complete and there is no need for WaitIO() to
Wait().

>Why a Wait() _after_ the WaitIO() request doesn't block, I'm not sure...

The signal bit was probably left on because the device did a
ReplyMsg(), but WaitIO() never called Wait(), so the mn_ReplyPorts's
signal bit was never cleared, but you can't rely on this!  Your
program will probably hang under certain (hard to reproduce)
conditions.  The moral is: Don't call Wait() to wait for the
mn_ReplyPort's signal because it might or might not have been cleared
(or even set if the request was completed quick).

In summary, WaitIO() knows how IO works so you don't need to.  You can
ignore all these details about IO handling if you remember what Bob
Burns pointed out in an earlier followup.  To abort IO requests (yes,
even timer.device requests):

	AbortIO(Req);
	(void)WaitIO(Req);

The (void) above indicates that we don't care what the result
(io_Error) of the request was.

-hans

kodiak@amiga.UUCP (Robert R. Burns) (11/26/89)

In article <5509@cps3xx.UUCP> porkka@frith.UUCP (Joe Porkka) writes:
)A related question: In general (any specifics please) is the following
)sequence of calls valid:
)	
)	p = CreateExtIO(myport, sizeof(*p));
)	OpenDevice(device.name , 0, p, flags);
)
)	/* Note that there are *no* SendIO(p) or DoIO(p) calls here */
)	AbortIO(p)
)	WaitIO(p);
)
)	/* Finish clean up here */
)
)The only thing that I think may have problems is the WaitIO(p) call.
)Would it?

This example is not valid.  CreateExtIO/OpenDevice does not guarantee
that the message type is ever set to NT_REPLYMSG, so WaitIO will
actually Wait -- you'll never get to your cleanup code.

- Kodiak
-- 
Bob Burns, amiga!kodiak						 _
	| /_  _|. _ |		   Commodore __			|_) _ |_  _ )'
	|<(_)(_)|(_\|<		    /\ |  ||| _` /\		|_)(_\| )(_\ |
	| \ Software		___/..\|\/|||__|/..\___			 Faith