You're exactly right.  Your example shows the way I prefer, and the way we
went with FB4.  I studiously avoided saying CFLOCK, rather just saying
locked, because there are different ways to go about locking stuff.  CFLOCK
just happens to be one that CF provides explicitly.

If we take our example another step and mix some user-specific data in
there, then we can create a new race condition that that mechanism won't
solve.

<cfscript>
  if (NOT isDefined("application.init")) {
    // something that takes a long time
    temp.userTracker = createObject("component", "path.to.userTracker");
    temp.userTracker.init();
    temp.othervar = 3;

    structAppend(application, temp, true);
    application.init = 1;
  }
  application.userTracker.addUser(session.user.userID);
</cfscript>

This is again contrived, but it's possible that two users will request this,
and the second user will reinitialize the CFC, nullifying the first users's
addUser() call.

Here we need to halt execution on the second request until the first request
finished initialization, so the second request doesn't get below the
initialization block until initialization is complete, but doesn't rexecute
the initialization block either.  CFLOCK is the only answer I've found for
this situation, though I suppose you could put a short Thread.wait() inside
a while loop that does the same thing as the CFLOCK.

barneyb

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of Matt Liotta
> Sent: Wednesday, December 03, 2003 1:21 PM
> To: [EMAIL PROTECTED]
> Subject: Re: [CFCDev] Basic CFC Design Question
> 
> > <cfif not isDefined("application.init")>
> >   <cfset application.myvar = 3 />
> >   <cfset application.othervar = application.myvar />
> >   <cfset application.myvar = application.myvar + 3 />
> >   <cfset application.thirdvar = application.myvar * 4 />
> >   <cfset application.init = 1 />
> > </cfif>
> >
> > Surely it's a contrived example, but if multiple threads executed it
> > concurrently, it's entirely possible that 'othervar' and 'thirdvar' 
> > could
> > contain inappropriate values.
> >
> That's is true, but it is also a perfect example of where 
> using a lock 
> is probably the wrong way to go. Consider the following instead.
> 
> <cfscript>
>       if(not IsDefined("application.init")) {
>               init = StructNew();
>               init.myvar = 3;
>               init.othervar = myvar;
>               init.myvar = myvar + 3;
>               init.thirdvar = myvar + 4;
> 
>               application.init = init;
>       }
> </cfscript>
> 
> Now the above still has the race condition, but it doesn't actually 
> matter and avoids the lock. Interestingly enough, examples like this 
> tend to perform better when an application variable is 
> initialized too 
> many times vs. just once, but the other threads have to wait on it.
> 
> Matt Liotta
> President & CEO
> Montara Software, Inc.
> http://www.MontaraSoftware.com
> (888) 408-0900 x901
> 
> 
> ----------------------------------------------------------
> 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