зеркало из https://github.com/mozilla/gecko-dev.git
bug #104769 (r=pavlov@netscape.com, sr=jst@netscape.com) Opening new windows sometimes stalls...
This commit is contained in:
Родитель
e7a0620006
Коммит
a749fe10c6
|
@ -109,6 +109,8 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// XXX For now ignore the cache key. We will need it in the future
|
||||
// for correctly dealing with image load requests that are a result
|
||||
// of post data.
|
||||
|
@ -152,6 +154,43 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Get the current EventQueue... This is used as a cacheId to prevent
|
||||
// sharing requests which are being loaded across multiple event queues...
|
||||
//
|
||||
nsCOMPtr<nsIEventQueueService> eventQService;
|
||||
nsCOMPtr<nsIEventQueue> activeQ;
|
||||
|
||||
eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
void *cacheId = activeQ.get();
|
||||
PRBool bCanCacheRequest = PR_TRUE;
|
||||
if (request) {
|
||||
if (!request->IsReusable(cacheId)) {
|
||||
//
|
||||
// The current request is still being loaded and lives on a different
|
||||
// event queue.
|
||||
//
|
||||
// Since its event queue is NOT active, do not reuse this imgRequest !!
|
||||
// Instead, force a new request to be created but DO NOT allow it to be
|
||||
// cached!
|
||||
//
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- DANGER!! Unable to use cached imgRequest [request=%p]\n", this, request));
|
||||
|
||||
entry = nsnull;
|
||||
NS_RELEASE(request);
|
||||
|
||||
bCanCacheRequest = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!request) {
|
||||
/* no request from the cache. do a new load */
|
||||
LOG_SCOPE(gImgLog, "imgLoader::LoadImage |cache miss|");
|
||||
|
@ -177,9 +216,12 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Created new imgRequest [request=%p]\n", this, request));
|
||||
|
||||
imgCache::Put(aURI, request, getter_AddRefs(entry));
|
||||
// Add the new request into the imgCache if its cachable...
|
||||
if (bCanCacheRequest) {
|
||||
imgCache::Put(aURI, request, getter_AddRefs(entry));
|
||||
}
|
||||
|
||||
request->Init(newChannel, entry);
|
||||
request->Init(newChannel, entry, cacheId);
|
||||
|
||||
PR_LOG(gImgLog, PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n", this));
|
||||
|
@ -249,7 +291,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
|
||||
LOG_MSG(gImgLog, "imgLoader::LoadImage", "creating proxy request.");
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, aLoadFlags, aRequest, _retval);
|
||||
rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, aLoadFlags, aRequest, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
|
@ -263,6 +305,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
{
|
||||
NS_ASSERTION(channel, "imgLoader::LoadImageWithChannel -- NULL channel pointer");
|
||||
|
||||
nsresult rv;
|
||||
imgRequest *request = nsnull;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
@ -281,6 +324,21 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
|
||||
*listener = nsnull; // give them back a null nsIStreamListener
|
||||
} else {
|
||||
//
|
||||
// Get the current EventQueue... This is used as a cacheId to prevent
|
||||
// sharing requests which are being loaded across multiple event queues...
|
||||
//
|
||||
nsCOMPtr<nsIEventQueueService> eventQService;
|
||||
nsCOMPtr<nsIEventQueue> activeQ;
|
||||
|
||||
eventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = eventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(activeQ));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
NS_NEWXPCOM(request, imgRequest);
|
||||
if (!request) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -288,7 +346,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
|
||||
imgCache::Put(uri, request, getter_AddRefs(entry));
|
||||
|
||||
request->Init(channel, entry);
|
||||
request->Init(channel, entry, activeQ.get());
|
||||
|
||||
ProxyListener *pl = new ProxyListener(NS_STATIC_CAST(nsIStreamListener *, request));
|
||||
if (!pl) {
|
||||
|
@ -307,7 +365,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, loadGroup, aObserver, cx, nsIRequest::LOAD_NORMAL, nsnull, _retval);
|
||||
rv = CreateNewProxyForRequest(request, loadGroup, aObserver, cx, nsIRequest::LOAD_NORMAL, nsnull, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS6(imgRequest, imgILoad,
|
|||
imgRequest::imgRequest() :
|
||||
mObservers(0),
|
||||
mLoading(PR_FALSE), mProcessing(PR_FALSE),
|
||||
mImageStatus(imgIRequest::STATUS_NONE), mState(0)
|
||||
mImageStatus(imgIRequest::STATUS_NONE), mState(0), mCacheId(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
|
@ -68,7 +68,9 @@ imgRequest::~imgRequest()
|
|||
/* destructor code */
|
||||
}
|
||||
|
||||
nsresult imgRequest::Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry)
|
||||
nsresult imgRequest::Init(nsIChannel *aChannel,
|
||||
nsICacheEntryDescriptor *aCacheEntry,
|
||||
void *aCacheId)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequest::Init");
|
||||
|
||||
|
@ -86,6 +88,8 @@ nsresult imgRequest::Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheE
|
|||
|
||||
mCacheEntry = aCacheEntry;
|
||||
|
||||
mCacheId = aCacheId;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,13 +61,20 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsresult Init(nsIChannel *aChannel, nsICacheEntryDescriptor *aCacheEntry);
|
||||
nsresult Init(nsIChannel *aChannel,
|
||||
nsICacheEntryDescriptor *aCacheEntry,
|
||||
void *aCacheId);
|
||||
|
||||
nsresult AddProxy (imgRequestProxy *proxy);
|
||||
nsresult RemoveProxy(imgRequestProxy *proxy, nsresult aStatus);
|
||||
|
||||
void SniffMimeType(const char *buf, PRUint32 len);
|
||||
|
||||
// a request is "reusable" if it has already been loaded, or it is
|
||||
// currently being loaded on the same event queue as the new request
|
||||
// being made...
|
||||
PRBool IsReusable(void *aCacheId) { return !mLoading || (aCacheId == mCacheId); }
|
||||
|
||||
private:
|
||||
friend class imgRequestProxy;
|
||||
|
||||
|
@ -106,6 +113,8 @@ private:
|
|||
nsCString mContentType;
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; /* we hold on to this to this so long as we have observers */
|
||||
|
||||
void *mCacheId;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче