[jbosscache-issues] [JBoss JIRA] (JBCACHE-1620) Race condition when automatically creating parent nodes during locking fails to get lock
Dennis Reed (JIRA)
jira-events at lists.jboss.org
Thu Aug 2 15:26:07 EDT 2012
[ https://issues.jboss.org/browse/JBCACHE-1620?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12709551#comment-12709551 ]
Dennis Reed commented on JBCACHE-1620:
--------------------------------------
One failure scenario this can cause:
Several HTTP requests are processed at the same time as soon as the node is started.
Thread1 wants to write /JSESSION/ib_localhost/foo
Thread2 wants to write /JSESSION/ib_localhost/bar
Thread1 tries to lock /JSESSION/ib_localhost/foo
Thread2 tries to lock /JSESSION/ib_localhost/bar
The lock call is handled by JBoss Cache's PessimisticNodeBasedLockManager
It loops through trying to get locks on /, /JSESSION, /JSESSION/ib_localhost, and /JSESSION/ib_localhost/xxx.
If the node already exists, it tries to get a read lock (except for /JSESSION/ib_localhost/xxx where it gets a write lock).
If the node doesn't exist, it creates it and gets a write lock.
The bug/race condition is in PessimisticUnversionedNode#addChildAndAcquireLock
If two threads try to create the same node at the exact same time, one thread creates it and gets a write lock.
The other thread returns the previously created node and DOES NOT LOCK IT.
So:
At startup, only the node / exists in the cache.
Thread1 gets a read lock on /
Thread2 gets a read lock on /
Thread1 sees that /JSESSION does not exist, and calls addChildAndAcquireLock
Thread2 sees that /JSESSION does not exist, and calls addChildAndAcquireLock
Thread1 creates the node and gets a write lock
Thread2 returns the node created by Thread1 without a lock
Thread1 sees that /JSESSION/ib_localhost does not exist, and calls addChildAndAcquireLock
Thread2 sees that /JSESSION/ib_localhost does not exist, and calls addChildAndAcquireLock
Thread2 creates the node and gets a write lock
Thread1 returns the node created by Thread2 without a lock
At this point the locks are:
Thread1:
/ read
/JSESSION write
/JSESSION/ib_localhost none
Thread2:
/ read
/JSESSION none
/JSESSION/ib_localhost write
Both threads then create their /JSESSION/ib_localhost/xxx and populate the data.
Both threads then make another cache call that need the same locks.
Thread1 already has a read lock on /, and a write lock on /JSESSION. It wants a read lock on /JSESSION/ib_localhost but has to wait on Thread2's write lock
Thread2 already has a read lock on /. It wants a read lock on /JSESSION but has to wait on Thread1's write lock.
DEADLOCK
> Race condition when automatically creating parent nodes during locking fails to get lock
> ----------------------------------------------------------------------------------------
>
> Key: JBCACHE-1620
> URL: https://issues.jboss.org/browse/JBCACHE-1620
> Project: JBoss Cache
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Components: Locking
> Affects Versions: 3.2.9.GA
> Reporter: Dennis Reed
> Assignee: Dennis Reed
>
> Bug/race condition in PessimisticUnversionedNode#addChildAndAcquireLock.
> If two threads try to create the same node at the exact same time, one thread creates it and gets a write lock.
> The other thread does not create a node, but returns the previously created node and does not lock it.
> The only caller PessimisticNodeBasedLockManager assumes the node was both created and locked after the call returns.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.jboss.org/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jbosscache-issues
mailing list