[comp.sys.amiga.tech] PIPE: and AmigaDOS bug

jep@mtiame.oz (Jesper Peterson) (05/03/90)

In article <ROSENBER.90May2001409@ra.abo.fi> rosenber@ra.abo.fi (Robin Rosenberg INF) writes:
|There is a bug it seems in AmigaDOS 1.3 that can cause problems when a
|handler is refered to the first time. AmigaDOS may load the handler
|TWICE and create two processes when there should be only one. I had some 
|trouble debugging the following little simple script:

[ script deleted ]

|It seems AmigaDOS can be fooled to load a handler TWICE. 
|Theory:
|	TEE needs pipe:
|	Dos finds out that it has to load pipe: and starts loading it
|	Meanwhile TYPE needs pipe: and dos again finds out that pipe: has to
|	be loaded. Dos doesn't know that it is doing this already and starts
|	loading the pipe handler for the second time.
|	The result is that TEE is talking to one pipe: and TYPE to another.
|

It isn't a bug. sometimes you actually DO want handlers to get "loaded" 
for each Open() on them eg. CON:.

When a handler starts it has to indicate whether it should be "forked"
as shared text or if packets should go to the "old" instance of the handler.
The default is to fork. The handler will fork if either ??_Port or ??_Task
is NULL. ?? is the device node structure prefix (dn_ perhaps?). When I say
_either_ Port or Task I just mean that don't remember which of them it is as
I normally use a template of a handler to create new ones (I'll create a new
handler for even the most stupid reason).

A *really* well behaved handler should probably Delay() then check if
it is already in the device list and abort if it finds "itself".
In reality you don't do this of course, so you are correct in your analysis
when you suggest it is a race condition.

Jesper


-- 
ACSnet: jep@mtiame.mtia.oz                 "This lottery is my bathroom."
UUCP:	...!uunet!munnari!mtiame.oz!jep       - Peg (Married with Children)
PHONE: (03) 699-1022

bader+@andrew.cmu.edu (Miles Bader) (05/04/90)

jep@mtiame.oz (Jesper Peterson) writes:
> |It seems AmigaDOS can be fooled to load a handler TWICE. 
> |Theory:
> |       TEE needs pipe:
> |       Dos finds out that it has to load pipe: and starts loading it
> |       Meanwhile TYPE needs pipe: and dos again finds out that pipe: has to
> |       be loaded. Dos doesn't know that it is doing this already and starts
> |       loading the pipe handler for the second time.
> |       The result is that TEE is talking to one pipe: and TYPE to another.

> A *really* well behaved handler should probably Delay() then check if
> it is already in the device list and abort if it finds "itself".
> In reality you don't do this of course, so you are correct in your analysis
> when you suggest it is a race condition.

The system should hold a lock while it checks to see if the device is there,
and if it finds that it's not, put a dummy entry in the device list that just
says "It's being loaded", then release the lock and proceed to load the
device.  Any other tasks that find the dummy entry while they're looking for
the device can just block until it gets loaded (using whatever mechanism, I
don't know what it would be).

-Miles

koren@hpfelg.HP.COM (Steve Koren) (05/04/90)

> Sksh 1.4 is a great improvement: it is good enough to replace
 
> Could the UNIX << stdin redirection be implemented?

I think so, but I have to fiddle with the parser a little first; it
is currently limited to 1023 character tokens, which removes much
of the capability of <<! style redirection.  Its on my list of
enhacements though...

> Could the & be made a synonym for 'srun' or a subshell?

Yes, but I "deferred" that enhancement; I'll see if I can manage to
briefly explain why.  Running an *external* program in the background is
a piece of cake.  However, I wanted the ability to use the '&' suffix
to run *anything* in the background.  For example, this works fine
in Un*x under ksh (just a dumb example):

  ( while true
    do
       rm -f ~/.sh_history
       sleep 30
    done ) &

In that case, the shell must fork itself; the child process then
runs the subshell script in the background.  That is the problem; I'm
sure its possible to do on the Amiga, but at the moment its not at 
all obvious to me how to make the shell fork itself.  (Creating a
task, not a process, has the severe limitation that you can't do
I/O).  If I can ever figure out how to do this without a lot of work,
I'll put it in, and it will use the '&' suffix.  What I really want
is an equivilant to the Un*x fork() command (which is very different
than Lattice's forkv() call).

> How difficult is it to use the PIPE: device for simultanous
> pipes?  Steve's pipes.readme suggests that it can handle one
> such pipe at a time - is it because he is trying to use the
> same pipe: file name between three programs?

No.  I don't know why it is (yet :-).  It is trying to run the first two
programs in the background (with Arp's ASyncRun()) and the last one in
the pipeline in the foreground.  For example,

   a | b | c

runs a and b asynchronously, with c in the foreground.  However, for
some reason this crashes the machine.  You can observe this behaviour
in SKsh 1.4 if you enable real pipes as discussed in the pipes.readme
file and pipe something through three commands like that.  (Make sure
you are in a state where your machine can crash though!)  I have
very carefully watched the data going into ASyncRun and SyncRun for
all three command calls, and it looks fine to me.  If bad data was
going in I could fix it, but I'm really confused now.

> It's a great program, Steve.

Thanks!

   - steve