Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Sep 1995 16:01:26 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        mpp@mpp.minn.net (Mike Pritchard)
Cc:        terry@lambert.org, nate@rocky.sri.MT.net, davidg@root.com, hackers@freefall.freebsd.org
Subject:   Re: Coding style ( was Re: why is this not a bug in namei?)
Message-ID:  <199509202301.QAA01780@phaeton.artisoft.com>
In-Reply-To: <199509202158.QAA12896@mpp.minn.net> from "Mike Pritchard" at Sep 20, 95 04:58:44 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> My previous example was very simplistic.  Having to lock multiple objects 
> during a function wasn't not uncommon.
> E.g.
> 
> 	XXX_LOCK();
> 	...
> 	if (error_condition) {
> 		XXX_UNLOCK();
> 		return (EWHATEVER);
> 	}
> 	...
> 	XXX_UNLOCK();
> 	...
> 	if (error_condition2)
> 		return (EHWATEVER);
> 	...
> 	YYY_LOCK();
> 	...
> 	if (error_condition2) {
> 		YYY_UNLOCK();
> 		return (EWHATEVER);
> 	}
> 	...
> 	YYY_UNLOCK();
> 	return (0);
> 
> In the above example, with gotos you would need 4 exit points:  1 for 
> an exit without any error.  And one each for each of the 3 error 
> conditions, since they all have different requirements.  2 of them have
> different locks, and 1 has no locks at all.

I think we are getting confused between function single entry/exit and
lock metastate single threading.

 	XXX_LOCK();
 	...
 	if (error_condition) {
 		err = EWHATEVER;
		goto error;
 	}
	...
 	XXX_UNLOCK();
 	...
 	if (error_condition2) {
 		err = EHWATEVER;
		goto error;
	}
 	...
 	YYY_LOCK();
 	...
 	if (error_condition2) {
 		err = EWHATEVER;
	} else {
		...
 	}

 	YYY_UNLOCK();

 error:
	return( err);
 

Again, this one leads to case simplification to simply:

 	XXX_LOCK();
 	...
 	if (!error_condition) {
		...
	}
	XXX_UNLOCK();
 	if (!error_condition) {
		...
		if (error_condition2) {
			err = EHWATEVER;
		} else {
			...
			YYY_LOCK();
			...
			if (error_condition2) {
				err = EWHATEVER;
			} else {
				...
			}
			YYY_UNLOCK();
		}
	} else {
		err = EWHATEVER;
	}
	return( err);


I think for a "goto" example, you'll need a cyclic graph.  And then
I will defend the existance of the goto.  8-).

Cyclic graphs exist in the code; they just aren't very common.

Directory reaversal in ufs_vnops.c:ufs_rename() is one good example,
though they are hidden by a pretty much bogus division of lookup()
into lookup() and relookup() (namei/lookup/relookup are simply some
of the worst code in the file system code path).

The current cycles in vfs_syscalls.c:mount() (update/nonupdate cases)
and vfs_syscalls.c:open(), rename(), etc. are caused by a flag omission
and a 6 line addition being missing from in 4 cases, and a bad job of
code overloading of not-very-common code in 3 others.

It's very hard to find an example that I would mung up with goto's
in the current code (I've added 4 "bogus_namei:" labels with one
goto each in 4 different functions, each XXX commented for future
cleanup when namei() is fixed.  They are not intended as permanent
features).  Certainly, I object to the "update:" and "out:" labels in
mount() much more.


					Regards,
					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509202301.QAA01780>