[comp.sys.amiga] Comments on the uniqueness of task & window id's

bryce@COGSCI.BERKELEY.EDU (Bryce Nesbitt) (06/26/87)

It just hit home that task & window id's are not really guaranteed to be
unique.  It's a longshot, but a task or window could disappear, and a new one
be created in it's place.  There would be no totally safe way of determining
if what is at that location is that same window/task you talked to last time.

99999 out of every 100000 Amiga programs won't need it, but my latest creation
could make use of a 100% unique task key.  Possibly a sequential long,
incremented and checked for uniqueness (You never know when that
4,294,967,296th task will start up!!) (I believe in truly infinite systems)

As it is there is a safe enough way for my program to work without this,
and I can also check things like the stack pointers etc.  But I'm fanatic about
reliability, so this does not sit very well.

Observation:  All those LONGs end up on WORD boundaries because of the size of
the node structure. 

|\ /|  . Ack! (NAK, EOT, SOH)
{O O} . 
( " )	bryce@cogsci.berkeley.EDU -or- ucbvax!cogsci!bryce
  U	using a task with the INTERACTIVE bit set. :-)

qix@ihlpa.ATT.COM (Puckett) (06/27/87)

In article <8706260543.AA20346@cogsci.berkeley.edu>, bryce@COGSCI.BERKELEY.EDU (Bryce Nesbitt) writes:
> It just hit home that task & window id's are not really guaranteed to be
> unique.  It's a longshot, but a task or window could disappear, and a new one
> be created in it's place.  There would be no totally safe way of determining
> if what is at that location is that same window/task you talked to last time.
> 
> 99999 out of every 100000 Amiga programs won't need it, but my latest creation
> could make use of a 100% unique task key.  Possibly a sequential long,
> incremented and checked for uniqueness (You never know when that
> 4,294,967,296th task will start up!!) (I believe in truly infinite systems)
> 
> As it is there is a safe enough way for my program to work without this,
> and I can also check things like the stack pointers etc.  But I'm fanatic about
> reliability, so this does not sit very well.

ID-handler was written based on these same fears.
It always returns a new number each time it is called (unless you wrap it
around after 10**16 accesses :-).  So a task can call it and get back a
number suitable for unique (long-term) task (or whatever) identification.

My application was to allocate pipe names for shell pipelines.  Suppose:

	1>  producer | filter_1 | filter_2 | . . . | filter_n

is desired.  Now you typically want to start all n+1 processes concurrently.
This allows for maximum utilization of the CPU.  We can implement it so:

	Run producer >pipe_1
	Run filter_1 <pipe_1 >pipe_2
	Run filter_2 <pipe_2 >pipe_3
		.
		.
		.
	Run filter_n-1 <pipe_n-1 >pipe_n
	filter_n <pipe_n

The last filter can be "Run" if the pipeline is to be a background job.

Basing the pipe names on Amiga processid's may not work.  Suppose
pipe names are generated by concatenating pipe_i with the shell's
processid.  This works until a shell (possibly a background job running
a script) produces such a pipeline and then goes away, and then another
shell appears in its same place (it must be Friday the 13th!).  If
this shell tries to produce a similar pipeline, there could be name
conflicts with the extant pipes from the previous shell.

I don't believe in using DateStamps to obtain uniqueness (e.g., combination
of an existing identifier + DateStamp) on the Amiga because the date is too
easily changed.  Imagine some process initiated in your Startup-Sequence
which *must* have a unique identifier, uses its processid + DateStamp
(not arithmetic +), and then the owner changes the date (because no
battery-backed clock).  It is possible that another process will now obtain
the same "unique" id using the DateStamp (though admittedly unlikely).

An approach like ID-handler seemed the safest to me, and requires little
extra effort.

			-Ed Puckett.

peter@sugar.UUCP (Peter DaSilva) (07/12/87)

> processid.  This works until a shell (possibly a background job running
> a script) produces such a pipeline and then goes away, and then another
> shell appears in its same place (it must be Friday the 13th!).  If
> this shell tries to produce a similar pipeline, there could be name
> conflicts with the extant pipes from the previous shell.

Do what UNIX programs do to create files in /tmp. What you do
is: 

	Create name filename.digits.A
	begin:
		Examine it.
		If it exists, create name filename.digits.B,
			and try again.
	end:
	create the file and boogie.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter (I said, NO PHOTOS!)

jesup@mizar.steinmetz (Randell Jesup) (07/20/87)

In article <386@sugar.UUCP> peter@sugar.UUCP (Peter DaSilva) writes:
>Do what UNIX programs do to create files in /tmp. What you do
>is: 
>	Create name filename.digits.A
>	begin:
>		Examine it.
>		If it exists, create name filename.digits.B,
>			and try again.
>	end:
>	create the file and boogie.

Just make sure digits are unique to the running program.  Otherwise, you get
into the old 'works except on a full moon when two copies are running at the
exact same time doing the same thing' problem.  Most problems of unique files
and ports can be solved with Forbid(), Permit(), and FindPort().

	Randell Jesup
	jesup@steinmetz.uucp
	jesup@ge-crd.arpa

rap@dana.UUCP (Rob Peck) (07/23/87)

In article <6752@steinmetz.steinmetz.UUCP>, jesup@mizar.steinmetz (Randell Jesup) writes:
> In article <386@sugar.UUCP> peter@sugar.UUCP (Peter DaSilva) writes:
> >Do what UNIX programs do to create files in /tmp. What you do
> >is: 
> 
> Just make sure digits are unique to the running program.  Otherwise, you get
> into the old 'works except on a full moon when two copies are running at the
> exact same time doing the same thing' problem.  Most problems of unique files
> and ports can be solved with Forbid(), Permit(), and FindPort().

I encountered a problem that couldnt be solved with Forbid(), Permit() and
FindPort().  In particular, I created a master program, that called
test().  test() is something that runs a graphics demo of some kind;
it creates a window of a fixed size, and puts it on a custom screen
whose address it locates by issuing FindPort(myscreen).  An addendum
to the port structure itself is the address of the custom screen.

The master program NOW does:

	Disable();
	port = FindPort(myscreen);
	if(port == 0)
		/* .... create the port if not there ... */
		/* open a custom screen, put the address of
		 * custom screen into addendum to the port;
		 * set users_of_screen = 1
		 */
	Enable();
	test();
	...    	 users_of_screen = users_of_screen -1;

		 (another addendum to the custom port)

	if(users_of_screen = 0) CloseScreen(myscreen);

All programs that are linked with this master routine are supposed to
look first to see if a custom screen exists, create it if not there,
then delete it if they are the last user.

I tried using Forbid() and Permit() in place of Disable(), and Enable(),
but when I tried doing:

	run program1
	run program2	(quickly typed after the first one)

	I got a lot of disk thrashing (as I expected, since it tried
	to load both at once).  And I got TWO custom screens.

(I dont recall exactly how much code I was trying to Forbid() or
Permit() around, but it was, I believe, not quite as large as
indicated above.  Maybe if I had just put Forbid() and Permit()
around finding, then creating a port - then using a Semaphore of some
kind when trying to access the port... but something (don't quite
know what) caused the above technique to pass fine if Disable/Enable
instead of Forbid/Permit while the second program was loading from
the disk.

Just thought I'd mention it.

Email me if you'd like to get a copy of the code.

Rob Peck.	...ihnp4!hplabs!dana!rap

jesup@mizar.steinmetz (Randell Jesup) (07/24/87)

In article <198@dana.UUCP> rap@dana.UUCP (Rob Peck) writes:
>I encountered a problem that couldnt be solved with Forbid(), Permit() and
>FindPort().  In particular, I created a master program, that called
>test().  test() is something that runs a graphics demo of some kind;
>it creates a window of a fixed size, and puts it on a custom screen
>whose address it locates by issuing FindPort(myscreen).  An addendum
>to the port structure itself is the address of the custom screen.
>
>The master program NOW does:
>
>	Disable();
>	port = FindPort(myscreen);
>	if(port == 0)
>		/* .... create the port if not there ... */
>		/* open a custom screen, put the address of
>		 * custom screen into addendum to the port;
>		 * set users_of_screen = 1
>		 */
>	Enable();
>	test();
>	...    	 users_of_screen = users_of_screen -1;
>
>		 (another addendum to the custom port)
>
>	if(users_of_screen = 0) CloseScreen(myscreen);
...
>Rob Peck.	...ihnp4!hplabs!dana!rap

	How about this:  (By the way, how is your port associated with
			  you Screen???)
main()
{
	...
	Forbid();
	if (port = FindPort(myportname))
	{
		<somehow find the Screen from the port>
		<update user count by 1>
	} else {
		<create port, set user count to 1>
		<Open screen, put in port>
		/* you might not want to forbid that long, so you might
		   want to set users to 0 until the screen opened, and
		   have somewthing that finds the port busy wait on the
		   Screen variable.  A bit bizarre, and I think it's ok
		   to open a screen inside a Forbid(). */
	}
	Permit();

	Test();
	...

	Forbid();
	if (<user count> = 1)
	{
		CloseScreen(<screen>);
		RemPort(myportname);
	} else
		<user count>--;
	Permit();
	...
}

	Actually, if I wanted to bother learning how they work I'm sure that
semaphores would make this easier.  Most problems I've dealt with using
Forbid and Permit were coming up with unique ports, for example for a shell
that has a port for receiving messages from sub-processes.  I just Forbid,
and then look for Shell_port_1.  If it's there, I look for shell_port_2, etc.
When I've found an unused port, I create it, then Permit.

	Randell Jesup
	jesup@ge-crd.arpa
	jesup@steinmetz.uucp (uunet!steinmetz!jesup)

jdow@pnet02.CTS.COM (Joanne Dow) (07/27/87)

> if(port == 0)
Perhaps change that 0 to 0L?
<@_@>

jdow@bix
UUCP: {cbosgd, hplabs!hp-sdd, ihnp4}!crash!gryphon!pnet02!jdow
INET: jdow@pnet02.CTS.COM

mwm@eris.BERKELEY.EDU (Mike (My watch has windows) Meyer) (07/28/87)

Sorry, but I seem to have missed the start of this. But anyway...

In article <1067@gryphon.CTS.COM> jdow@pnet02.CTS.COM (Joanne Dow) writes:
<> if(port == 0)
<Perhaps change that 0 to 0L?

Only if your compiler is broken. Manx incorrectly issues a warning if
port is a pointer type. I have been told (but haven't verified) that
changing this to "if (!port)" will cause that message to vanish.

	<mike
--
Take a magic carpet to the olden days			Mike Meyer
To a mythical land where everybody lays			ucbvax!mwm
Around in the clouds in a happy daze			mwm@berkeley.edu
In Kizmiaz ... Kizmiaz					mwm@ucbjade.BITNET