Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 67876 invoked by uid 500); 1 Sep 2001 16:24:50 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 67865 invoked from network); 1 Sep 2001 16:24:49 -0000 From: "Greg Marr" Subject: Re: cvs commit: apr/threadproc/win32 thread.c To: dev@apr.apache.org X-Mailer: CommuniGate Pro Web Mailer v.3.4.6 Date: Sat, 01 Sep 2001 12:29:53 -0400 Message-ID: In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 8bit X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N On Sat, 1 Sep 2001 11:18:47 +0200 "Sander Striker" wrote: > > rbb 01/09/01 00:29:07 > > APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t > *control, > > void (*func)(void)) > > { > > + /* Quick escape hatch, and bug fix. > > This still isn't correct. Now we have a race condition that > could result in the function never being called instead of once. > This looks better IMHO: > > if (!InterlockedExchange(&control->value, 1)) > func(); > > return APR_SUCCESS; To also include the quick escape hatch: /* Save the system call if InterlockedExchange can't possibly return 0. The InterlockedExchange function returns the *old* value of the variable. If it is 0, this is the first function to make it 1, and so the function should be called. */ if ((0 == control->value) && (0 == InterlockedExchange(&control->value, 1))) func(); return APR_SUCCESS; BTW, I looked at doing this with InterlockedIncrement, since it returns the new value, except that Win95 is broken, and it just returns non-zero on success, not necessarily the new value.