[comp.sys.amiga] Using Software Interrupts for Menu Handling

drs-ano@duvan.nada.kth.se (Gunnar Nordmark) (06/16/88)

I have set up a IDCMP port that generates software interrupts when
messages arrive. It works great!
The window is opened with CON: and I have it as stdin for the program.
When you call fgets(buf,stdin) the program requests input from CON:
and goes to sleep until you type a <RETURN>.
The problem is that if you select QUIT from the menu, you would like
to leave the program instantly, not after the fgets() has returned.

Is there a way to abort the fgets()?  Can I send a packet to the
device driver that forces it to return my readrequest with an error?

Carolyn? Andy? (or some other CON: packet wizard?)

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

hawes@dino.ulowell.edu (Bill Hawes) (06/21/88)

You can abort the fgets() by simply sending a close packet to the console
handler.  The read in progress will terminate and you'll be able to exit
cleanly.  (But be sure to set a flag so you don't try to close down again,
and you'll either have to release the filehandle yourself, or clear the
fh_Type field and close it as a NIL: filehandle).

Let me know how it works.

  -Bill Hawes (ConMan author)

(BTW, closing with a read pending will work with ConMan 1.1, but not prior
versions.  The ED editor is the only software I know that does this)

dillon@CORY.BERKELEY.EDU (Matt Dillon) (06/22/88)

>You can abort the fgets() by simply sending a close packet to the console
>handler.  The read in progress will terminate and you'll be able to exit

	close ??  CMD_FLUSH is what you meant.  I haven't tried this, but
it ought to work.  The nice thing about using CMD_FLUSH is that you can do
it multiple times.

	CLOSEing the file handle would probably crash the machine!  In
fact, sending any DOS packet from a software interrupt might crash the 
machine because DOS can only handle waiting for one response at a time
(because it expects the returned packet to be the first msg on the port).

					-Matt

jesup@cbmvax.UUCP (Randell Jesup) (06/22/88)

In article <8806212054.AA00815@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>	CLOSEing the file handle would probably crash the machine!  In
>fact, sending any DOS packet from a software interrupt might crash the 
>machine because DOS can only handle waiting for one response at a time
>(because it expects the returned packet to be the first msg on the port).

	Unless you install a pr_PacketWait handler....  However, I've never
heard of anyone doing this, though it should work.  Figuring out what
you should do will be the interesting part.  I wouldn't advise trying to
write such a beast in anything but asm.

Randell Jesup, Commodore Engineering {uunet|rutgers|ihnp4|allegra}!cbmvax!jesup

drs-ano@duvan.nada.kth.se (Gunnar Nordmark) (06/26/88)

In article <8806212054.AA00815@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>	close ??  CMD_FLUSH is what you meant.  I haven't tried this, but
>it ought to work.  The nice thing about using CMD_FLUSH is that you can do
>it multiple times.
>
>	CLOSEing the file handle would probably crash the machine!  In
>fact, sending any DOS packet from a software interrupt might crash the 
>machine because DOS can only handle waiting for one response at a time
>(because it expects the returned packet to be the first msg on the port).
>
>					-Matt

Good idea!  But it doesn't work, don't ask me why. RKM (AW page 45) states
that a CMD_FLUSH will return all pending I/O requests with an error,
but what happens in this case is that you get a copy of the last character
typed. An example:

First you do a
  fgets(buf, stdin);
this function will not return until it has collected a full line of text.
Then Charlie User starts typing some characters
  Hi, mom
Suddenly he gets restless and begins to play with the menus, he selects
  QUIT
This causes a softint that does
  finito=YES;
  ioreq->io_Command=CMD_FLUSH;
  ioreq->io_Device=conDevice;
  ioreq->io_Unit=(struct Unit *)conUnit;
  DoIO(ioreq);
However, the fgets() doesn't return. Instead a copy of the last character
typed appears on the screen.
  Hi, momm
The effect is exactly the same as if he had retyped the last character.

I haven't digged into the depths of the fgets() function, but I suspect the
problems lies in the CON: handler. I'm using ConMan 1.1 but I will try it
on a plain CON: to see if it behaves differently.

In any case this approach *ought to* work, (right Matt?), and I won't *ever*
give up my idea of letting software interrupts abort readrequests.
If I get it working, it will be possible to Intuitionize software written
for other computers with very little effort. You just call a customized
error-handling routine when a read-error occurs (which you would probably
do anyway) and that routine handles menus and gadgets for you.
A modular and elegant approach!

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

drs-ano@duvan.nada.kth.se (Gunnar Nordmark) (06/27/88)

In article <4080@cbmvax.UUCP> jesup@cbmvax.UUCP (Randell Jesup) writes:
>In article <8806212054.AA00815@cory.Berkeley.EDU> dillon@CORY.BERKELEY.EDU (Matt Dillon) writes:
>>	CLOSEing the file handle would probably crash the machine!  In
>>fact, sending any DOS packet from a software interrupt might crash the 
>>machine because DOS can only handle waiting for one response at a time
>>(because it expects the returned packet to be the first msg on the port).
>
>	Unless you install a pr_PacketWait handler....  However, I've never
>heard of anyone doing this, though it should work.  Figuring out what
>you should do will be the interesting part.  I wouldn't advise trying to
>write such a beast in anything but asm.
>
>Randell Jesup, Commodore Engineering {uunet|rutgers|ihnp4|allegra}!cbmvax!jesup

Great, I will start coding immediately! :-)
No, seriously, I think I'll do it another way (Jeez..., I'm a coward)
I'll just launch another process that can do the Close() for me. The
software interrupt wakes it up when the time has come.

The problem is, however, that I *do not* want to Close() the CON:
Why not?  Because it's my CLI-window!
I tried Matt's suggestion of CMD_FLUSHing the console.device that
CON: talks to, but no way. That villain (i.e. CON:) seems to ignore the
fact that it's CMD_READ returned early with an error. Sigh.
ConMan on the other hand doesn't precisely ignore the returned request,
it thinks it's a valid one resulting in a duplicate of the last typed
character.
(These are just wild guesses since I haven't the foggiest of what's going
on inside these handlers)

Maybe there are someone who does? 

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

jesup@cbmvax.UUCP (Randell Jesup) (06/29/88)

In article <432@draken.nada.kth.se> G@epsilon.stacken.kth.se (Gunnar Nordmark) writes:
>The problem is, however, that I *do not* want to Close() the CON:
>Why not?  Because it's my CLI-window!
>I tried Matt's suggestion of CMD_FLUSHing the console.device that
>CON: talks to, but no way. That villain (i.e. CON:) seems to ignore the
>fact that it's CMD_READ returned early with an error. Sigh.
>ConMan on the other hand doesn't precisely ignore the returned request,
>it thinks it's a valid one resulting in a duplicate of the last typed
>character.

	Try using something more low-level than "fgets".  God knows what that
is doing internally.  Use "Read" and see if you still have the problem.
Maybe try changing the window into raw IO (using ACTION_SET_MODE), and doing
WaitForChar()s so your quit will take place within a limited time.  You'll
have to do your own editing/echoing.

-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

hawes@dino.ulowell.edu (Bill Hawes) (07/04/88)

With regards to sending DOS packets from interrupt code, this shouldn't
really be a problem as long as the packets are being sent directly to the
handler.  All handlers have to be prepared to receive packets in any order
from many clients (this is a multi-tasking machine, isn't it?).

The only problems I see with sending a CLOSE packet asynchronously is to
make sure that the associated filehandle isn't closed again.  Of course,
this assumes that the user is allowed to close the filehandle at all --
not a nice thing to do with stdin.

  Bill

hawes@dino.ulowell.edu (Bill Hawes) (07/04/88)

Sending CMD_FLUSH to the console device directly won't work, as no matter
what was returned, the console handler will simply go back to read more.

If you're not in a position to try closing the console (ie if your program
doesn't really own it), all is not lost.  ConMan supports the ACTION_FLUSH
packet that empties the internal queues to get rid of any random stuff
that may have been typed but not yet returned, and supports a private
ACTION_FORCE packet (code 2001) that will place whatever characters you
send into the read stream, just like they had been typed.  The parameters
are the same for an ACTION_WRITE packet, so just send along a newline
or carriage return and fgets() will get unstuck.

I'm open to suggestions as to whether ACTION_FLSUH should knock any 
waiting read loose, or whether another mechanism is needed to effectively
abort a read operation.

  -Bill Hawes