From: bombadil@diku.dk (Kristian Nielsen)
Newsgroups: comp.sys.amiga.programmer
Subject: Re: A few Handler/FileSys Q's (Mod.Long.)
Keywords: handler filesystem packets Amiga DOS AmigaDOS lock FileLock
Date: 18 Dec 92 12:05:51 GMT
Organization: Department of Computer Science, U of Copenhagen

djung@economics.adelaide.edu.au (David Jung) writes:

>If I then open a second shell and type 'ls diskname:' (where diskname: is the
>disk I just ejected) - I get the usual "please insert volume diskname in any
>drive".  This is because DOS has discovered the volume node's dol_Task is NULL.

>OK - so far so good.

>Cancel the requester.  Now - with the disk still ejected - press the space bar
>in the more window until more runs out of buffered file and has to read more
>from the disk.  Now I get a "Please insert volume diskname in device df0:".
>(Note this also happens if the disk has been inserted into the other drive!!)
>(i.e. is wants me to remove it from df1 and insert it into df0!)

>Note that it wants df0 not any drive.  I ASSUME the following has happened.

>More has asked DOS to read more of the file, and DOS has used the FileLock's
>fl_Task field to decide which handler to send the packet to. (only place
>it can get it from since the volume node's dol_Task is NULL).

(the address of the packet is from the file handle, to be precise,
though this handle probably contains a lock to the file).

>The handler has recieved a packet containing a lock that it is no longer
>managing (no matching key or whatever) - and has put up the requester asking
>for the volume.  My questions are (finally)

>1) How can it do this??

>If it called AutoRequest() or ErrorReport() it would be tied up - but it
>still appears to be accepting packets.  If you repeat this whole thing but
>bring up two more windows, then after getting a requester from pressing space
>in the first more window - if you press space in the second window a second
>identical requester appears.  if my ASSUMPTION is correct - the handler has
>received another packet and done the same thing.

Usually, this feature is refered to by saying that the ROM filesystems
are multi-threaded. Now I don't claim to be an expert on the ROM file
systems, and I've never seen the actual code, of course. But from my own
experience with handlers and from various rumors I have some idea of how
this is done (hopefully someone will correct me if nessesary).

One way to achive multi-threadedness in a handler is to use coroutines
('Structured Computer Organisation' by Tannenbaum describe these; I
understand that they are also used in modula2). Basically, several
threads of executions are managed in a single task context. For example,
a filing system will communicate with trackdisk.device, timer.device,
applications (receiving packets) and intuition (for requesters). All of
these communications take place using exec messages. The handler has a
central loop waiting for messages on any of the corresponding ports.
Each time a message is received, the handler branches off to the
relevant code.

Now, say the handler has to put up a requester. This is done in the
usual way using EasyRequest() or whatever. The usual approach would
be to have some code like

	EasyRequest(winptr, &myrequest);
	WaitPort(myicdmport);

However, this would lock out *ANY* access to the file system while the
requester was being displayed. To avoid this, the WaitPort() is replaced
by a coroutine context switch to the coroutine doing the central handler
loop. Later, when the requester is satisfied, the coroutine doing the
EasyRequest() will be resumed.

The usual way to implement coroutines involve having seperate stacks for
each coroutine, swapping them when nessesary. The ROM file systems may
do it differently, we'd need one of the commodore gurus to give the
details.

>2) Is it legal, as a filesystem, to set the FileLock's fl_Task fields to
>NULL before putting them on the dol_LockList when a volume has been removed?
>Or is this rubbish. (wishfully thinking DOS might put up a requester for me)

Well, the term 'legal' is not particulary well defined when the
questions are about dos device handlers, since the documentation tends
to be VERY sparse. Still, I don't think it could possibly be valid to
zero the fl_Task field. You cannot rely on dos.library putting up
requesters since the packet may be sent directly from applications (ie.
ixemul.library by Marcus Wild). For this reason, lock->fl_Task MUST
remain valid at all times.

>3) As a filesystem, if a volume has just been inserted into the device you're
>managing, and you grab the locks from the dol_LockList, can you Forbid(), go
>through and change the fl_Task field of all the locks to yourself, then Permit()
>so that any further use of the active FileLocks will be directed to you?

(minor detail: in 2.0 you use LockDoslist() / UnlockDoslist() instead of
Forbid() / Permit(). )

I don't think this should be done. I can hardly imagine it's 'legal',
for one. Just imagine the instant disaster that would result if you
somehow mixed of a volume belonging to a completely alien file system!
Anyway, it shouldn't be nessesary to do this.

>4) If, again as a filesystem, I get an argument FileLock for a volume I am
>no longer managing (volume was ejected from my device), can I, upon inspection
>of the DosList finding a non-NULL dol_Task field, send the packet onto
>the other filesystem that is managing the volume now (assuming the dol_Task
>field is non-NULL because the volume has been inserted into another device).
>I would have to set up the packet so it was returned either to me, or directly
>to the application/DOS.

Again, the best thing to do would be to ask for the volume to be
inserted in the right drive.

[Aside: This asking the user to move the disk might seem unfriendly
(though it seldom occurs in practice; perhaps dos.library does some
magic with ASSIGNed names?). However, compare to msdos world; I've once
managed to trash a disk by swapping it while a file was open. The file
system assumed that the disk had not been changed and happily overwrote
the new disk with the sectors that belonged to the old one. It should be
easy to imagine the resulting disaster...]

	- Kristian.