From: Kalle Olavi Niemitalo
Subject: CLHS unwind-protect example
Date: 
Message-ID: <izn4rruv0xo.fsf@stekt34.oulu.fi>
CLHS has this in the description of UNWIND-PROTECT:

> The correct way to code this is as follows: 
> 
>  (let ((old-count *access-count*))
>    (unwind-protect
>      (progn (incf *access-count*)
> 	      (perform-access))
>      (setq *access-count* old-count)))

Because *ACCESS-COUNT* has stars around it, I guess it's a special
variable.  Would the following simpler code then do the same thing,
or is there some race condition I overlooked?

  (let ((*access-count* (1+ *access-count*)))
    (perform-access))

Is the example meant to demonstrate how such a counter could be
maintained in a more complex place, like (FOO-ACCESS-COUNT *FOO*)?

From: ···@itasoftware.com
Subject: Re: CLHS unwind-protect example
Date: 
Message-ID: <zo9mz6a4.fsf@itasoftware.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> CLHS has this in the description of UNWIND-PROTECT:
> 
> > The correct way to code this is as follows: 
> > 
> >  (let ((old-count *access-count*))
> >    (unwind-protect
> >      (progn (incf *access-count*)
> > 	      (perform-access))
> >      (setq *access-count* old-count)))
> 
> Because *ACCESS-COUNT* has stars around it, I guess it's a special
> variable.  Would the following simpler code then do the same thing,
> or is there some race condition I overlooked?
> 
>   (let ((*access-count* (1+ *access-count*)))
>     (perform-access))
> 

Typical multitasking implementations do not share the values of
special bindings across different tasks.  So you would not have a
race-condition, but the *access-count* would only correctly reflect
the `task-local' state.
From: Kalle Olavi Niemitalo
Subject: Re: CLHS unwind-protect example
Date: 
Message-ID: <iznsnfes4dn.fsf@stekt34.oulu.fi>
···@itasoftware.com writes:

> Typical multitasking implementations do not share the values of
> special bindings across different tasks.  So you would not have a
> race-condition, but the *access-count* would only correctly reflect
> the `task-local' state.

If multitasking is involved, I don't see how the original code would
work either.  If tasks A and B start running it in that order, and A
finishes its "access" first, then it restores the original value even
though B is still accessing the object.

It must be for some other reason.
From: Kaz Kylheku
Subject: Re: CLHS unwind-protect example
Date: 
Message-ID: <vBi97.28475$BN6.781551@news1.rdc1.bc.home.com>
In article <···············@stekt34.oulu.fi>, Kalle Olavi Niemitalo wrote:
>···@itasoftware.com writes:
>
>> Typical multitasking implementations do not share the values of
>> special bindings across different tasks.  So you would not have a
>> race-condition, but the *access-count* would only correctly reflect
>> the `task-local' state.
>
>If multitasking is involved, I don't see how the original code would
>work either.  If tasks A and B start running it in that order, and A
>finishes its "access" first, then it restores the original value even
>though B is still accessing the object.
>
>It must be for some other reason.

That reason would be thread-specific environments for special variable
binding, which would mean that effectively, each thread has its own
*access-count* variable which has nothing to do with any other 
thread's *access-count*.
From: Barry Margolin
Subject: Re: CLHS unwind-protect example
Date: 
Message-ID: <FtC97.16$TO3.218@burlma1-snr2>
In article <···············@stekt34.oulu.fi>,
Kalle Olavi Niemitalo  <···@iki.fi> wrote:
>CLHS has this in the description of UNWIND-PROTECT:
>
>> The correct way to code this is as follows: 
>> 
>>  (let ((old-count *access-count*))
>>    (unwind-protect
>>      (progn (incf *access-count*)
>> 	      (perform-access))
>>      (setq *access-count* old-count)))
>
>Because *ACCESS-COUNT* has stars around it, I guess it's a special
>variable.  Would the following simpler code then do the same thing,
>or is there some race condition I overlooked?
>
>  (let ((*access-count* (1+ *access-count*)))
>    (perform-access))
>
>Is the example meant to demonstrate how such a counter could be
>maintained in a more complex place, like (FOO-ACCESS-COUNT *FOO*)?

You must understand the example in its proper context.  The purpose of that
example is to show how to use UNWIND-PROTECT properly, not to show the best
way to implement temporary updating of a variable.

If the counter were in the slot of a structure rather than a special
variable, the form of the example code would stay the same, but LET
wouldn't be available to perform the temporary binding.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.