Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Nov 2001 14:22:46 -0800 (PST)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Archie Cobbs <archie@dellroad.org>
Cc:        cvs-committers@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   Re: cvs commit: src/sys/kern kern_timeout.c src/sys/sys callout.
Message-ID:  <XFMail.011113142246.jhb@FreeBSD.org>
In-Reply-To: <200111132134.fADLYVu59037@arch20m.dellroad.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 13-Nov-01 Archie Cobbs wrote:
> John Baldwin writes:
>> >     sys/kern             kern_timeout.c 
>> >     sys/sys              callout.h 
>> >   Log:
>> >   MFC: Change callout_stop() to return an integer.
>> 
>> ??  Is this needed for something in 4.x?  The only thing it is used for in
>> 5.x
>> is to work around a really obscure race involving the endtsleep() timeout.
> 
> Yes, at least I think so.. :-)
> 
> The problem I am trying to solve is: suppose you have some object
> (blob of memory) with a reference count. You only free the object
> when the ref count goes to zero.
> 
> If you do a callout_reset() using the object as the handler
> argument, obviously you'd want to add a reference. When your
> handler eventually gets invoked, you want to remove a reference.
> 
> Now what if you call callout_stop()? That functions does not
> guarantee that your handler won't be called -- because your
> event might have been dequeued and just about to be called,
> but hasn't actually been called yet. Therefore, you don't know
> whether to decrement the reference count or not, unless you
> have some indication from callout_stop() about whether the
> funny case of dequeued-but-not-handled-yet has happened or not.
> 
> My analysis may be incorrect, in which case I would love for
> someone to explain all this to me because it seems pretty subtle.

Yes, it is useful in this case.  However, all this tells you is that the
handler has been dequeued.  You don't know if it has already run or will run
in the future however.  Determining that is another trick.  For the
endtsleep race, we use the TDF_TIMOFAIL flag to test this.  In the case you
describe I think it is simpler though as the timeout will always do the
decrement, so you simply don't decrement if the callout_stop() fails.

-- 

John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message




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