Skip to content

Commit

Permalink
Fix deadlock in SoftReferenceCache apply function.
Browse files Browse the repository at this point in the history
When we find a stale SoftReference, release the read lock, then acquire
the write lock, double-check that the reference is still stale, and then
finally remove the entry from the cache.
  • Loading branch information
Shadowfiend committed Sep 14, 2012
1 parent 9714074 commit 9dc6352
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions core/util/src/main/scala/net/liftweb/util/SoftReferenceCache.scala
Expand Up @@ -118,15 +118,28 @@ class SoftReferenceCache[K, V](cacheSize: Int) {
* @param key
* @return Box[V]
*/
def apply(key: K): Box[V] = lock(readLock) {
Box.!!(cache.get(key)) match {
case Full(value) =>
Box.!!(value.get) or {
remove(key);
Empty
def apply(key: K): Box[V] = {
val (doRemove:Boolean, retval:Box[V]) =
lock(readLock) {
Box.!!(cache.get(key)) match {
case Full(value) =>
Box.!!(value.get).map((false, _)) openOr {
(true, Empty)
}
case _ => (false, Empty)
}
case _ => Empty
}

if (doRemove) {
lock(writeLock) {
val value = cache.get(key)

if (value != null && value.get == null)
remove(key)
}
}

retval
}

/**
Expand Down

1 comment on commit 9dc6352

@fmpwizard
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Please sign in to comment.