You're right; my apologies.  I always lock the first test (using a temp
variable), which, as you say, alleviates the problem, and I didn't fully
consider the repercussions.

However that lock can be read-only, so it doesn't single-thread anything:

<cflock type="readonly">
  <cfset reload = NOT structKeyExists(application, "foo") />
</cflock>
<cfif reload>
  <cflock type="exclusive">
    <cfif NOT structKeyExists(application, "foo")>
      <cfset application.foo = createObject("component", "foo") />
      <cfset application.foo.init() />
    </cfif>
  </cflock>
</cfif>

Cheers,
barneyb

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of Sean A Corfield
> Sent: Tuesday, March 16, 2004 2:25 PM
> To: [EMAIL PROTECTED]
> Subject: Re: [CFCDev] Returing "THIS" from init(), WAS: RFC, 
> CFC Best Practices
> 
> On Mar 16, 2004, at 1:57 PM, Barney Boisvert wrote:
> > Your CFLOCK eliminates the difference between the two examples.
> 
> No it doesn't - the first example is *not* thread safe. I 
> guarantee it. 
> We know it from experience, trust me on this one!
> 
> > This is the first reasonably compelling argument for putting 
> > createObject()
> > and init() together, so I want to make sure I understand right.
> 
> I'll explain the thread-safety problem...
> 
> . Two requests come in about the same time - and application.foo has 
> not yet been created/initialized.
> 
> . Thread 1 gets as far as creating foo and setting 
> application.foo but 
> has not yet run init().
> 
> . Thread 2 gets to the test for application.foo existing and 
> it passes.
> 
> . Thread 2 then goes off and uses application.foo (possibly while 
> thread 1 is initializing it).
> 
> . Thread 2 bails because application.foo was not properly initialized 
> before use.
> 
> There are of course several solutions to this (in addition to the 
> method chaining approach). One is to lock *outside* the first 
> <cfif> - 
> the downside is that every single request has to lock (and 
> single-thread that test) which is a performance bottleneck. 
> Another is 
> to change the outer (and inner) tests to include 
> application.foo.isInitialized() - the downsides are (a) extra code 
> needs to be executed on every request and (b) you now need an 
> additional method on foo and requires the pseudo-constructor 
> set a flag 
> and the init() method set a flags (added complexity).
> 
> Regards,
> Sean
> 
> ----------------------------------------------------------
> You are subscribed to cfcdev. To unsubscribe, send an email
> to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
> in the message of the email.
> 
> CFCDev is run by CFCZone (www.cfczone.org) and supported
> by Mindtool, Corporation (www.mindtool.com).
> 
> An archive of the CFCDev list is available at 
> www.mail-archive.com/[EMAIL PROTECTED]
> 

----------------------------------------------------------
You are subscribed to cfcdev. To unsubscribe, send an email
to [EMAIL PROTECTED] with the words 'unsubscribe cfcdev' 
in the message of the email.

CFCDev is run by CFCZone (www.cfczone.org) and supported
by Mindtool, Corporation (www.mindtool.com).

An archive of the CFCDev list is available at www.mail-archive.com/[EMAIL PROTECTED]

Reply via email to