Permalink
Browse files

Fix deadlock in SoftReferenceCache apply function.

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...
1 parent 2e4c662 commit a3dcc266e8c60cfe3ef89eeb838b4fe978f5c9ad @Shadowfiend Shadowfiend committed with nafg Sep 14, 2012
Showing with 20 additions and 7 deletions.
  1. +20 −7 core/util/src/main/scala/net/liftweb/util/SoftReferenceCache.scala
@@ -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
}
/**

0 comments on commit a3dcc26

Please sign in to comment.