cvs commit: src/sys/kern kern_proc.c
Nate Lawson
nate at root.org
Wed Jun 9 16:26:36 GMT 2004
On Wed, 9 Jun 2004, Poul-Henning Kamp wrote:
> In message <20040609.100413.118633043.imp at bsdimp.com>, "M. Warner Losh" writes:
> >Can you provide a couple of lines about why BAD is BAD and why GOOD
> >fixes that flaw? That should help others from making this mistake in
> >the future.
>
> The way to fix this is to make sure that the test for zero-ness
> is done on the result of our own decrement operation:
>
> LOCK(foo->lock)
> i = --foo->refcount;
> UNLOCK(foo->lock)
> if (i == 0)
> destroy(foo);
>
> Assume foo->refcount = 2;
>
> thread1 (low priority) thread2 (high priority)
> ---------------------- -----------------------
>
> ... ...
> LOCK(foo->lock) ...
> i = --foo->refcount; LOCK(foo->lock)
> # i == 1, refcount == 1
> UNLOCK(foo->lock)
> i = --foo->refcount;
> # i == 0, refcount == 0
> UNLOCK(foo->lock)
> if (i == 0) # true
> destroy(foo)
> ...
>
> if (i == 0) # false
> destroy(foo)
>
> I'm not very good at explaining this am I ?
The only potential remaining problem is if another thread can increment
the refcount after the unlock and i == 0 comparison but before
"free(foo)". In this case, you'll free an object that is still in use.
It's safe to hold locks across free(), that's how I handle this case.
-Nate
More information about the cvs-src
mailing list