Bug 1032992 - Set mHasData in CacheEntry when metadata are filled but no data are written, r=michal

This commit is contained in:
Honza Bambas 2014-07-07 20:58:26 +02:00
parent f24a6ffa54
commit ea6bc303ad
4 changed files with 53 additions and 1 deletions

View File

@ -849,6 +849,21 @@ void CacheEntry::OnHandleClosed(CacheEntryHandle const* aHandle)
mState = READY;
}
if (mState == READY && !mHasData) {
// We may get to this state when following steps happen:
// 1. a new entry is given to a consumer
// 2. the consumer calls MetaDataReady(), we transit to READY
// 3. abandons the entry w/o opening the output stream, mHasData left false
//
// In this case any following consumer will get a ready entry (with metadata)
// but in state like the entry data write was still happening (was in progress)
// and will indefinitely wait for the entry data or even the entry itself when
// RECHECK_AFTER_WRITE is returned from onCacheEntryCheck.
LOG((" we are in READY state, pretend we have data regardless it"
" has actully been never touched"));
mHasData = true;
}
InvokeCallbacks();
}

View File

@ -45,6 +45,8 @@ const NOTWANTED = 1 << 11;
const COMPLETE = 1 << 12;
// Don't write meta/data and don't set valid in the callback, consumer will do it manually
const DONTFILL = 1 << 13;
// Used in combination with METAONLY, don't call setValid() on the entry after metadata has been set
const DONTSETVALID = 1 << 14;
var log_c2 = true;
function LOG_C2(o, m)
@ -192,8 +194,13 @@ OpenCallback.prototype =
entry.metaDataReady();
if (self.behavior & METAONLY) {
// Since forcing GC/CC doesn't trigger OnWriterClosed, we have to set the entry valid manually :(
entry.setValid();
if (!(self.behavior & DONTSETVALID))
entry.setValid();
entry.close();
if (self.behavior & WAITFORWRITE)
self.goon(entry);
return;
}
do_execute_soon(function() { // emulate more network latency

View File

@ -0,0 +1,27 @@
function run_test()
{
do_get_profile();
if (!newCacheBackEndUsed()) {
do_check_true(true, "This test doesn't run when the old cache back end is used since the behavior is different");
return;
}
// Open for write, but never write and never mark valid
asyncOpenCacheEntry("http://no-data/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
new OpenCallback(NEW|METAONLY|DONTSETVALID|WAITFORWRITE, "meta", "", function(entry) {
// Open again, we must get the callback and zero-length data
do_execute_soon(() => {
Cu.forceGC(); // invokes OnHandleClosed on the entry
asyncOpenCacheEntry("http://no-data/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
new OpenCallback(NORMAL, "meta", "", function(entry) {
finish_cache2_test();
})
);
});
})
);
do_test_pending();
}

View File

@ -64,6 +64,9 @@ skip-if = os == "android"
[test_cache2-24-exists.js]
# Bug 675039, comment 6: "The difference is that the memory cache is disabled in Armv6 builds."
skip-if = os == "android"
[test_cache2-26-no-outputstream-open.js]
# GC, that this patch is depenedent on, doesn't work well on Android."
skip-if = os == "android"
[test_304_responses.js]
# Bug 675039: test hangs on Android-armv6
skip-if = os == "android"