tracker issue : CF-3662524

select a category, or use search below
(searches all categories and all time range)
Title:

Request is unable to reacquire the same named lock

| View in Tracker

Status/Resolution/Reason: Closed/Withdrawn/NotABug

Reporter/Name(from Bugbase): Bradley Wood / Bradley Wood (Bradley Wood)

Created: 11/11/2013

Components: Core Runtime

Versions: 10.0

Failure Type: Crash

Found In Build/Fixed In Build: Final /

Priority/Frequency: Critical / All users will encounter

Locale/System: English / Windows 7 SP1 64-bit

Vote Count: 1

Problem Description: My understanding is that ColdFusion supports a style of reentrant locks where the same request can reacquire the same lock again.  I've had a very hard time confirming in the docs, please correct me if I am wrong with a link to documentation.  The issue is that if a request has obtained a named readonly lock, it will not be able to acquire an exclusive lock of the same name.  There is no meaningful error, the cflock tag just times out.  It appears that the exclusive lock is timing out because it's being blocked by the readonly lock even though it's held by the SAME request.

Steps to Reproduce:

<cflock name="myLock" type="readonly" timeout="1">
	<cflock name="myLock" type="exclusive" timeout="1"></cflock>
</cflock>

Actual Result:

A timeout occurred while attempting to lock myLock.

Expected Result:

It is expected that myLock will be successfully escalated to an exclusive lock.  The readonly lock should not block since it's owned by the same thread.  

Any Workarounds:

None that I know of.  

It's worth nothing that if both locks are readonly it works.  
If both locks are exclusive it works.  
And, if the outer lock is exclusive and the inner lock is readonly it works.  
The only scenario where ColdFusion fails to obtain the inner lock is when the outer lock is readonly and the inner lock is exclusive.

The code to reproduce above is very minimalistic.  In case anyone wants a good use case, consider a shared resource with a getter that acquires readonly access and a setter that requires exclusive access.  (I'm using the server scope, but pretend it's some outside caching mechanism)


<cffunction name="get">
	<cflock name="foo_access" type="readonly" timeout="1">
		<cfif !isdefined("server.foo")>
			<cfset set()>
		</cfif>
		<cfreturn server.foo>
	</cflock>
</cffunction>

<cffunction name="set">
	<cflock name="foo_access" type="exclusive" timeout="1">
		<cfif !isdefined("server.foo")>
			<cfset server.foo = "bar">
		</cfif>
	</cflock>	
</cffunction>

<cfoutput>
#get()#
</cfoutput>

----------------------------- Additional Watson Details -----------------------------

Watson Bug ID:	3662524

External Customer Info:
External Company:  
External Customer Name: bradwood.com
External Customer Email:  
External Test Config: My Hardware and Environment details:



Server Product	 ColdFusion

Version	 10,0,11,285437

Tomcat Version	 7.0.23.0

Edition	 Developer  

Serial Number	 Developer  

Operating System	 Windows 7  

OS Version	 6.1  

Update Level	 /C:/ColdFusion10/cfusion/lib/updates/chf10000011.jar  

Adobe Driver Version	 4.1 (Build 0001)  



Java Version	 1.7.0_15  

Java Vendor	 Oracle Corporation

Attachments:

Comments:

Should be consistent behavior for all re-entrant locking scenarios within the same request/thread.
Vote by External U.
14014 | November 12, 2013 01:19:47 AM GMT
Here's the documentation of coldfusion 10 locking http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec22c24-7cc4.html. --Copied from the documentation Note: You cannot upgrade or downgrade a lock from one type to another. In other words, do not nest an exclusive lock in a read-only lock of the same name or scope; the exclusive lock will always time out. Also, do not nest a read-only lock inside an exclusive lock with the same name or scope; doing so has no effect. --Thanks
Comment by S V.
14011 | November 12, 2013 03:44:37 AM GMT
Ahh, thank you for that info. I googled for probably 45 minutes and scanned that exact link multiple times last night but somehow never found that one little paragraph. So it's good to know that this behavior actually _is_ documented which I suppose makes it not a bug, though it's a bit confusing that the behavior differs based on the order of the locks. I'd like to hear if there is a technical reason for the restriction or if it's simply the way it's always been done. Upgrading lock types is a common scenario (specifically in database contexts) but I think the key might be that SQL Server uses an intent exclusive lock to signal that it might upgrade and after further thought I think that is the reason it won't work here. Two threads hitting the same code would share the read lock, but neither would be able to obtain the exclusive lock. Databases get around this by having a read lock, intent exclusive lock, and exclusive lock. Where the middle type is compat with the first, but not itself or the last. Drat, I think I've answered the technical reason... In this case, I'd like to suggest that a proper error be thrown explaining that changing lock types is not allowed instead of timing out. Should I open a separate ticket for that?
Comment by External U.
14012 | November 12, 2013 10:15:09 AM GMT
Can you please log a seperate bug for the error message. Please quote this bug number in the new bug for reference. Thanks -Viny (Comment added from ex-user id:vnigam)
Comment by Adobe D.
14013 | December 04, 2013 12:59:44 AM GMT