[appcache] Page using AppCache can not be opened again until cleaned all the offline website data.

RESOLVED FIXED in mozilla37

Status

()

RESOLVED FIXED
4 years ago
4 years ago

People

(Reporter: pzhang, Assigned: mayhemer)

Tracking

33 Branch
mozilla37
x86_64
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

(Reporter)

Description

4 years ago
Here is the steps to reproduce:
  - Create a new profile
  - Download cache files from:
    https://drive.google.com/file/d/0B8XSKtJgcYt1VTk3LW1LQ0wzREU/view
  - Extract the cache files into the cache directory of the created profile.
    The cache dir on Ubuntu is: ~/.cache/mozilla/firefox/%PROFILE_ID%/
  - Open Firefox with the profile and visit http://offlintab.firefoxchina.cn/
  - Open a new tab with http://offlintab.firefoxchina.cn/ again

Expected result:
  http://offlintab.firefoxchina.cn/ is opened

Actual result:
  Nothing happened except the page loading indicator is keeping spinning.

tested on Firefox35.0a2@Ubuntu14.04
(Reporter)

Comment 1

4 years ago
Tested on Firefox33.1.1@Ubuntu14.04, this issue is also valid.
(Assignee)

Updated

4 years ago
Assignee: nobody → honzab.moz
(Assignee)

Comment 2

4 years ago
The problem is in the following code:

nsresult
nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry *entry,
                                             bool aNew,
                                             nsIApplicationCache* aAppCache,
                                             nsresult status)
{
    nsresult rv;

    if (mCanceled) {
        LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
        return mStatus;
    }

    if (aAppCache) {
        if (mApplicationCache == aAppCache && !mCacheEntry) {
            // 1
            rv = OnOfflineCacheEntryAvailable(entry, aNew, aAppCache, status);
        }
        else if (mApplicationCacheForWrite == aAppCache && aNew && !mOfflineCacheEntry) {
            // 2
            rv = OnOfflineCacheEntryForWritingAvailable(entry, aAppCache, status);
        }
        else {
            // 3
            rv = OnOfflineCacheEntryAvailable(entry, aNew, aAppCache, status);
        }
    }


We get stuck on the second load because a channel used for processing the appcache update (invoked by the first load) indefinitely keeps the cache entry for write and blocks it for concurrent open.


More details:

We have a document (an implicit (master) entry) to download to the cache.

The implicit partial download for that top level document is having the current (most recent and now active) appcache as a cache to write to and looks for an appcache to potentially read from.

There is an appcache found to load the document from - the same as the one to write to (there is an entry in the sqlite db) but the file is deleted from some reason (an external fault or tempering).

Hence, the entry is not found in the chosen appcache group version (which is not expected).  During wait for the two callbacks for entries we first have to get the source entry and then the target entry.  For the source one we have to end up at // 3, for the target one at // 2, since mCacheEntry should not be null by that time (entry should be found).

But despite an appcache is found to load the source entry from, its load eventually fails, hence we end up at // 1 for the target entry ==> wait flags won't get properly dropped, channel hangs in background and hold the appcache entry forever ==> any other attempt to load the same URL from appcache hangs on  indefinite wait for the entry.

Patch coming.
(Assignee)

Updated

4 years ago
Status: NEW → ASSIGNED
(Assignee)

Comment 3

4 years ago
Created attachment 8526227 [details] [diff] [review]
v1

https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=65a8135225d3

the solution is following: when a channel is setup to choose an appcache to load from, a cache is found, but actual load of the entry (e.g. file not found later) fails, we must not set the mAppllicationCache member on the channel (it says which appcache we are working with) when there is an appcache to write to (mApplicationCacheForWrite).  That's only in situations like these, during cache updates.  Note we must set mAppllicationCache regardless of failure of the entry load in "normal" loading/reading case to stay consistent - here I mean to simply not break anything.
Attachment #8526227 - Flags: review?(jduell.mcbugs)
Comment on attachment 8526227 [details] [diff] [review]
v1

Review of attachment 8526227 [details] [diff] [review]:
-----------------------------------------------------------------

Makes sense to me.
Attachment #8526227 - Flags: review?(jduell.mcbugs) → review+
Hi, when will this patch be landed? Thanks.
(Reporter)

Comment 6

4 years ago
Hi Jason, when will this patch be landed? Thanks.
Flags: needinfo?(jduell.mcbugs)
Flags: needinfo?(jduell.mcbugs)
https://hg.mozilla.org/mozilla-central/rev/2b1ce9e015a4
Status: ASSIGNED → RESOLVED
Last Resolved: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla37
You need to log in before you can comment on or make changes to this bug.