🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #10160

Re: Manx help

#10160
From: Rob Peck
Date: Fri, 28 Oct 1988 19:28
141 lines
5469 bytes
In article <5918@killer.DALLAS.TX.US>, jdp@killer.DALLAS.TX.US (Jim Pritchett) writes:
> out?  Basically the problem is that although the test program below runs fine,
> the system becomes severely unstable and crashes within a couple of commands
> after the program terminates.  I'm sure that there is a problem with my
> (mis)understanding of locks, but I don't know what it is.  Here is the source
> code to my program (Aztec C v3.6a, SDB):
>  
>   lockram = Lock("ram:t", ACCESS_READ);
>   lockcd = CurrentDir(lockram);
>
	(material deleted for brevity)

>   UnLock(lockram);
>   lockram = CurrentDir(lockcd);
> 
	(material deleted for brevity)
> 
>   UnLock(lockcd);
>   UnLock(lockram);
>   

I experimented and found out (and documented it in the Programmers'
Guide) that you should NOT unlock a lock that you get from CurrentDir.

=======================================================================
AmigaLINE:  Care and Feeding of AmigaDOS 'locks'.   Rob Peck 


ONLY unlock locks that you get from Lock() or DupLock().  It seems that
when using CurrentDir(), the system simply hands you a pointer to a lock
that it already was using for something else... I believe it is the lock
associated with the current CLI's current directory.  If you unlock this,
you return the resource to the system which can then reuse that memory
For any other purpose.  The instability you see I believe is that the
CLI from which you started the program still has a pointer to that
memory and when it tries to use it for something, GURU (maybe).

The simplest experiment you can do to confirm this is the following
(done from memory cause my book is not here at this moment):

#include "exec/types.h"
#include "functions.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

main()  
{
	/* INCORRECT METHOD #1 */
	struct FileLock *testlock, *aarrgghh;
	testlock = Lock("RAM:",ACCESS_READ);
	aarrgghh = CurrentDir(testlock);
	UnLock(aarrgghh);
	UnLock(testlock);
}

#include "exec/types.h"
#include "functions.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

main()  
{
	/* INCORRECT METHOD #2 */
	struct FileLock *testlock, *aarrgghh;
	testlock = Lock("RAM:",ACCESS_READ);
	aarrgghh = CurrentDir(testlock);
	UnLock(aarrgghh);  /* see, did not even unlock testlock */
}

On exiting either version, try the command 'DIR', or 'LIST'.  
You may be surprised at the results.

This code WILL destabilize a system because CurrentDir returns a pointer
to the lock on the PREVIOUS directory, but puts the program into the
directory associated with the new lock you have obtained.  The purpose
for CurrentDir (and ParentDir) for that matter, returning the PREVIOUS
lock is so you can freely move around in the directory tree.  When
ParentDir returns a NULL BPTR, it means you are at the root of that
filing system and cannot parent-up any further, but you do get the
pointer to the lock on the previous directory so that you can move
back down to wherever you wish to go.  Likewise with CurrentDir, you
get the previous one so that, for example, your program can go out
of the current directory to retrieve music or other files to which
you have been given a lock (for example in a Workbench argument),
then come back to your own current directory to retrieve other
files you may need - that directory from whence you started:

	newlock = Lock("new.directory", ACCESS_READ);

	oldlock = CurrentDir(newlock);
	/* do stuff in new directory */
	ignoredlock = CurrentDir(oldlock);
	/* returns you to where you started. */

Notice that I called this one "ignored lock" because once I finished
with the new directory, I was given a pointer to the lock that I
had handed to CurrentDir earlier.  So I can safely ignore it if
I simply remember to UnLock(newlock) later, because in this case,

	ignoredlock == newlock

which simply means that if you UnLock something given to you by
CurrentDir AND unlock something given to you by Lock, you are
unlocking the same thing TWICE, ... same effect as freeing the
same memory twice and the system fails eventually.

So the RULE is:

	NEVER UnLock any lock given to you by either
	CurrentDir() or ParentDir().  ONLY UnLock a
	lock provided to you by Lock() or DupLock().
	Those BELONG to you.  The others just might
	have been created by the system and it will
	not realize you have killed them -- when it
	tries to reuse them, the GURU may visit.


#include "exec/types.h"
#include "functions.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

main()  
{
	/* CORRECT METHOD */

	struct FileLock *testlock, *aarrgghh;
	testlock = Lock("RAM:",ACCESS_READ);
	aarrgghh = CurrentDir(testlock);

	/* aarrgghh is a pointer to the lock on the
	 * directory that the CLI started from...
	 * it may still need that lock sometime later.
	 * If we free it by UnLock, we mess things up.
	 */

	UnLock(testlock);
	/* Did nothing more than move current CLI's
	 * current directory to ram:
	 */
}
Technical Details
Message-ID: <679@ardent.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!ubvax!ardent!rap
References: <5918@killer.DALLAS.TX.US>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!ubvax!ardent!rap
From: rap@ardent.UUCP (Rob Peck)
Newsgroups: comp.sys.amiga.tech
Subject: Re: Manx help
Keywords: Manx Aztec DOS Locks
Message-ID: <679@ardent.UUCP>
Date: 28 Oct 88 19:28:56 GMT
References: <5918@killer.DALLAS.TX.US>
Organization: Dana Computer, Inc., Sunnyvale, CA
Lines: 141