Bug 460037 - Fix crasher in font loader when closing windows. r+sr=roc

This commit is contained in:
John Daggett 2008-12-12 16:31:51 +09:00
Родитель 9025de0ae1
Коммит 1a7886ee8c
5 изменённых файлов: 96 добавлений и 109 удалений

Просмотреть файл

@ -144,24 +144,10 @@ class gfxProxyFontEntry;
class THEBES_API gfxUserFontSet {
public:
class LoaderContext;
typedef nsresult (*LoaderCallback) (gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc,
LoaderContext *aContextData);
class LoaderContext {
public:
LoaderContext(LoaderCallback aLoader)
: mUserFontSet(nsnull), mLoaderProc(aLoader) { }
virtual ~LoaderContext() { }
gfxUserFontSet* mUserFontSet;
LoaderCallback mLoaderProc;
};
THEBES_INLINE_DECL_REFCOUNTING(gfxUserFontSet)
gfxUserFontSet(LoaderContext *aContext);
gfxUserFontSet();
virtual ~gfxUserFontSet();
enum {
@ -201,7 +187,13 @@ public:
// lookup a font entry for a given style, returns null if not loaded
gfxFontEntry *FindFontEntry(const nsAString& aName,
const gfxFontStyle& aFontStyle, PRBool& aNeedsBold);
const gfxFontStyle& aFontStyle,
PRBool& aNeedsBold);
// initialize the process that loads external font data, which upon
// completion will call OnLoadComplete method
virtual nsresult StartLoad(gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc) = 0;
// when download has been completed, pass back data here
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
@ -232,9 +224,6 @@ protected:
nsRefPtrHashtable<nsStringHashKey, gfxMixedFontFamily> mFontFamilies;
PRUint64 mGeneration;
// owned by user font set obj, deleted within destructor
nsAutoPtr<LoaderContext> mLoaderContext;
};
// acts a placeholder until the real font is downloaded

Просмотреть файл

@ -109,13 +109,9 @@ gfxMixedFontFamily::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[],
}
gfxUserFontSet::gfxUserFontSet(LoaderContext *aContext)
: mLoaderContext(aContext)
gfxUserFontSet::gfxUserFontSet()
{
NS_ASSERTION(mLoaderContext, "font set loader context not initialized");
mFontFamilies.Init(5);
mLoaderContext->mUserFontSet = this;
IncrementGeneration();
}
@ -280,10 +276,6 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
NS_ASSERTION(aProxyEntry->mSrcIndex < numSrc, "already at the end of the src list for user font");
NS_ASSERTION(mLoaderContext, "user font loader context not initialized");
if (!mLoaderContext)
return STATUS_ERROR;
if (aProxyEntry->mIsLoading) {
aProxyEntry->mSrcIndex++;
} else {
@ -319,8 +311,7 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
else {
if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI,
currSrc.mFormatFlags)) {
nsresult rv = mLoaderContext->mLoaderProc(aProxyEntry, &currSrc,
mLoaderContext);
nsresult rv = StartLoad(aProxyEntry, &currSrc);
PRBool loadOK = NS_SUCCEEDED(rv);
if (loadOK) {

Просмотреть файл

@ -1787,16 +1787,9 @@ nsPresContext::FlushUserFontSet()
NS_IF_RELEASE(mUserFontSet);
if (rules.Length() > 0) {
nsFontFaceLoaderContext *loaderCtx =
new nsFontFaceLoaderContext(this);
if (!loaderCtx)
gfxUserFontSet *fs = new nsUserFontSet(this);
if (!fs)
return;
gfxUserFontSet *fs = new gfxUserFontSet(loaderCtx);
// user font set owns loader context
if (!fs) {
delete loaderCtx;
return;
}
mUserFontSet = fs;
NS_ADDREF(mUserFontSet);

Просмотреть файл

@ -78,8 +78,8 @@ static PRLogModuleInfo *gFontDownloaderLog = PR_NewLogModule("fontdownloader");
nsFontFaceLoader::nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI,
gfxUserFontSet::LoaderContext *aContext)
: mFontEntry(aFontToLoad), mFontURI(aFontURI), mLoaderContext(aContext)
nsIPresShell *aShell)
: mFontEntry(aFontToLoad), mFontURI(aFontURI), mShell(aShell)
{
}
@ -115,19 +115,26 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
PRBool fontUpdate;
// first, check to make sure we're not torn down
if (mShell->IsDestroying()) {
return aStatus;
}
nsPresContext *ctx = mShell->GetPresContext();
if (!ctx) {
return aStatus;
}
// whether an error occurred or not, notify the user font set of the completion
fontUpdate = mLoaderContext->mUserFontSet->OnLoadComplete(mFontEntry, aLoader,
aString, aStringLen,
aStatus);
fontUpdate = ctx->GetUserFontSet()->OnLoadComplete(mFontEntry, aLoader,
aString, aStringLen,
aStatus);
// when new font loaded, need to reflow
if (fontUpdate) {
nsFontFaceLoaderContext *loaderCtx
= static_cast<nsFontFaceLoaderContext*> (mLoaderContext);
// Update layout for the presence of the new font. Since this is
// asynchronous, reflows will coalesce.
loaderCtx->mPresContext->UserFontSetUpdated();
ctx->UserFontSetUpdated();
LOG(("fontdownloader (%p) reflow\n", this));
}
@ -135,17 +142,53 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
}
nsresult
nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc,
gfxUserFontSet::LoaderContext *aContext)
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext)
{
nsresult rv;
if (!aSourcePrincipal)
return NS_OK;
// check content policy
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
aTargetURI,
aSourcePrincipal,
aContext,
EmptyCString(), // mime type
nsnull,
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
return NS_ERROR_CONTENT_BLOCKED;
}
return NS_OK;
}
nsUserFontSet::nsUserFontSet(nsPresContext *aContext)
: mPresContext(aContext)
{
NS_ASSERTION(mPresContext, "null context passed to nsUserFontSet");
}
nsUserFontSet::~nsUserFontSet()
{
}
nsresult
nsUserFontSet::StartLoad(gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc)
{
nsresult rv;
// check same-site origin
nsFontFaceLoaderContext *loaderCtx
= static_cast<nsFontFaceLoaderContext*> (aContext);
nsIPresShell *ps = loaderCtx->mPresContext->PresShell();
nsIPresShell *ps = mPresContext->PresShell();
if (!ps)
return NS_ERROR_FAILURE;
@ -166,7 +209,8 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
principal = do_QueryInterface(aFontFaceSrc->mOriginPrincipal);
}
rv = CheckLoadAllowed(principal, aFontFaceSrc->mURI, ps->GetDocument());
rv = nsFontFaceLoader::CheckLoadAllowed(principal, aFontFaceSrc->mURI,
ps->GetDocument());
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
if (LOG_ENABLED()) {
@ -184,7 +228,7 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
nsRefPtr<nsFontFaceLoader> fontLoader = new nsFontFaceLoader(aFontToLoad,
aFontFaceSrc->mURI,
aContext);
ps);
if (!fontLoader)
return NS_ERROR_OUT_OF_MEMORY;
@ -238,34 +282,3 @@ nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad,
return rv;
}
nsresult
nsFontFaceLoader::CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext)
{
nsresult rv;
if (!aSourcePrincipal)
return NS_OK;
// check content policy
PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT,
aTargetURI,
aSourcePrincipal,
aContext,
EmptyCString(), // mime type
nsnull,
&shouldLoad,
nsContentUtils::GetContentPolicy(),
nsContentUtils::GetSecurityManager());
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
return NS_ERROR_CONTENT_BLOCKED;
}
return NS_OK;
}

Просмотреть файл

@ -42,12 +42,15 @@
#ifndef nsFontFaceLoader_h_
#define nsFontFaceLoader_h_
#include "nsCOMPtr.h"
#include "nsIPresShell.h"
#include "nsIStreamLoader.h"
#include "nsIURI.h"
#include "gfxUserFontSet.h"
class nsIRequest;
class nsISupports;
class nsIPresShell;
class nsPresContext;
class nsIPrincipal;
@ -56,7 +59,7 @@ class nsFontFaceLoader : public nsIStreamLoaderObserver
public:
nsFontFaceLoader(gfxFontEntry *aFontToLoad, nsIURI *aFontURI,
gfxUserFontSet::LoaderContext *aContext);
nsIPresShell *aShell);
virtual ~nsFontFaceLoader();
NS_DECL_ISUPPORTS
@ -65,33 +68,31 @@ public:
// initiate the load
nsresult Init();
// returns whether create succeeded or not
static nsresult CreateHandler(gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc,
gfxUserFontSet::LoaderContext *aContext);
private:
static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
nsIURI* aTargetURI,
nsISupports* aContext);
nsRefPtr<gfxFontEntry> mFontEntry;
nsCOMPtr<nsIURI> mFontURI;
gfxUserFontSet::LoaderContext* mLoaderContext;
private:
nsRefPtr<gfxFontEntry> mFontEntry;
nsCOMPtr<nsIURI> mFontURI;
nsCOMPtr<nsIPresShell> mShell;
};
class nsFontFaceLoaderContext : public gfxUserFontSet::LoaderContext {
// nsUserFontSet - defines the loading mechanism for downloadable fonts
class nsUserFontSet : public gfxUserFontSet
{
public:
nsFontFaceLoaderContext(nsPresContext* aContext)
: gfxUserFontSet::LoaderContext(nsFontFaceLoader::CreateHandler),
mPresContext(aContext)
{
nsUserFontSet(nsPresContext *aContext);
~nsUserFontSet();
}
nsPresContext* mPresContext;
// starts loading process, creating and initializing a nsFontFaceLoader obj
// returns whether load process successfully started or not
nsresult StartLoad(gfxFontEntry *aFontToLoad,
const gfxFontFaceSrc *aFontFaceSrc);
protected:
nsPresContext *mPresContext; // weak reference
};
#endif /* !defined(nsFontFaceLoader_h_) */