Heinz asks:

I saw that you have generated substitutions to user CF-tags in CFSCRIPT [at CFLIB].

My problem: I want to have a substitute for CFLOCK but CFLOCK has a start- and a end-tag!

Do you have a hint to solve this?

So, what Heinz is talking about is a set of UDFs I built that allow you to call CF tags in CFSCRIPT. You can find an entire library of them called CFMLLib. One example is WDDXSerialize. It allows you do stuff like this:

<cfscript>
x = arrayNew(1);
x[1] = now();
x[2] = structNew();
x[2].foo ="goo";
packet = wddxSerialize(x);
writeOutput(left(htmlEditFormat(packet),100));
</cfscript>

However, as Heinz points out, there is no way to duplicate the concept of locking, since locking involves wrapping a set of commands. So the short answer is - he is right. However, one of the best things about ColdFusion is that there is multiple ways to solve a problem.

Let's say you want to access a value in the Application scope, but others may access it as well, so you want to have a ReadOnly lock when reading it, and an exclusive lock when writing it. How about a simple UDF?

<cffunction name="scopeLockRead" output="false" returnType="any">
   <cfargument name="scope" type="string" required="true">
   <cfargument name="key" type="string" required="true">
   <cfargument name="timeout" type="numeric" required="false" default="30">
   <cfset var ptr ="">
   
   <cflock scope="#arguments.scope#" type="readOnly" timeout="#arguments.timeout#">
      <cfset ptr = structGet(arguments.scope)>
      <cfreturn duplicate(ptr[arguments.key])>
   </cflock>
</cffunction>

<cffunction name="scopeLockWrite" output="false" returnType="void">
   <cfargument name="scope" type="string" required="true">
   <cfargument name="key" type="string" required="true">
   <cfargument name="value" type="any" required="true">
   <cfargument name="timeout" type="numeric" required="false" default="30">
   <cfset var ptr ="">
   
   <cflock scope="#arguments.scope#" type="exclusive" timeout="#arguments.timeout#">
      <cfset ptr = structGet(arguments.scope)>
      <cfset ptr[arguments.key] = arguments.value>
   </cflock>
</cffunction>
      
<cfscript>
scopeLockWrite("server","counter", 100);
writeOutput(scopeLockRead("server","counter"));
</cfscript>

This example presents two UDFs. The first, scopeLockRead, will perform a locked read on the requested scope. The second one will do an update. Now - this doesn't give you exactly what you want, but it may be useful.

Another thing to consider. If your operation needs to be locked and you want to call the operation from cfscript, simply put the entire operation, including the locks, in a UDF. Don't forget that a UDF need not be a "generic utility", it could be very specific to your application. Once you have wrapped it up into a UDF, then you could easily call it from CFSCRIPT.

Anyone else have thoughts on this?