* When a vm_cache is merged with another one, we now remove the consumer; that allows
for an extra check in vm_cache_release_ref() as the cache shouldn't have any areas or consumers at this point. * Fixed a locking problem in vm_cache_remove_consumer(): the cache was acquired after its lock was gone, so someone else might have released in the mean time. * if the cache's source is to be replaced, we now no longer release its lock after having merged it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19570 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -183,6 +183,11 @@ vm_cache_release_ref(vm_cache_ref *cacheRef)
|
|||||||
|
|
||||||
// delete this cache
|
// delete this cache
|
||||||
|
|
||||||
|
if (cacheRef->areas != NULL)
|
||||||
|
panic("cache to be deleted still has areas");
|
||||||
|
if (!list_is_empty(&cacheRef->cache->consumers))
|
||||||
|
panic("cache %p to be deleted still has consumers", cacheRef->cache);
|
||||||
|
|
||||||
// delete the cache's backing store
|
// delete the cache's backing store
|
||||||
cacheRef->cache->store->ops->destroy(cacheRef->cache->store);
|
cacheRef->cache->store->ops->destroy(cacheRef->cache->store);
|
||||||
|
|
||||||
@@ -415,7 +420,7 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer)
|
|||||||
vm_cache_ref *consumerRef;
|
vm_cache_ref *consumerRef;
|
||||||
vm_page *page, *nextPage;
|
vm_page *page, *nextPage;
|
||||||
|
|
||||||
consumer = list_get_first_item(&cache->consumers);
|
consumer = list_remove_head_item(&cache->consumers);
|
||||||
consumerRef = consumer->ref;
|
consumerRef = consumer->ref;
|
||||||
|
|
||||||
mutex_lock(&consumerRef->lock);
|
mutex_lock(&consumerRef->lock);
|
||||||
@@ -445,12 +450,8 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer)
|
|||||||
mutex_unlock(&consumerRef->lock);
|
mutex_unlock(&consumerRef->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&cacheRef->lock);
|
|
||||||
|
|
||||||
if (newSource != NULL) {
|
if (newSource != NULL) {
|
||||||
// The remaining consumer has gotten a new source
|
// The remaining consumer has gotten a new source
|
||||||
mutex_lock(&cacheRef->lock);
|
|
||||||
|
|
||||||
list_remove_item(&newSource->consumers, cache);
|
list_remove_item(&newSource->consumers, cache);
|
||||||
list_add_item(&newSource->consumers, consumer);
|
list_add_item(&newSource->consumers, consumer);
|
||||||
consumer->source = newSource;
|
consumer->source = newSource;
|
||||||
@@ -461,7 +462,8 @@ vm_cache_remove_consumer(vm_cache_ref *cacheRef, vm_cache *consumer)
|
|||||||
// Release the other reference to the cache - we take over
|
// Release the other reference to the cache - we take over
|
||||||
// its reference of its source cache
|
// its reference of its source cache
|
||||||
vm_cache_release_ref(cacheRef);
|
vm_cache_release_ref(cacheRef);
|
||||||
}
|
} else
|
||||||
|
mutex_unlock(&cacheRef->lock);
|
||||||
|
|
||||||
vm_cache_release_ref(cacheRef);
|
vm_cache_release_ref(cacheRef);
|
||||||
}
|
}
|
||||||
@@ -481,9 +483,9 @@ vm_cache_add_consumer(vm_cache_ref *cacheRef, vm_cache *consumer)
|
|||||||
consumer->source = cacheRef->cache;
|
consumer->source = cacheRef->cache;
|
||||||
list_add_item(&cacheRef->cache->consumers, consumer);
|
list_add_item(&cacheRef->cache->consumers, consumer);
|
||||||
|
|
||||||
mutex_unlock(&cacheRef->lock);
|
|
||||||
|
|
||||||
vm_cache_acquire_ref(cacheRef);
|
vm_cache_acquire_ref(cacheRef);
|
||||||
|
|
||||||
|
mutex_unlock(&cacheRef->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user