Bug 642551. Save status info we may want to use in a list so we don't have to walk the entire pending request hashtable looking for one of the rare ones with status info. r=neil

This commit is contained in:
Boris Zbarsky 2011-09-06 22:57:46 -04:00
Родитель 4ba46f2e78
Коммит 8f47fec0f3
2 изменённых файлов: 58 добавлений и 34 удалений

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

@ -94,12 +94,38 @@ void GetURIStringFromRequest(nsIRequest* request, nsACString &name)
} }
#endif /* DEBUG */ #endif /* DEBUG */
struct nsStatusInfo : public PRCList
{
nsString mStatusMessage;
nsresult mStatusCode;
// Weak mRequest is ok; we'll be told if it decides to go away.
nsIRequest * const mRequest;
nsStatusInfo(nsIRequest *aRequest) :
mRequest(aRequest)
{
MOZ_COUNT_CTOR(nsStatusInfo);
PR_INIT_CLIST(this);
}
~nsStatusInfo()
{
MOZ_COUNT_DTOR(nsStatusInfo);
PR_REMOVE_LINK(this);
}
};
struct nsRequestInfo : public PLDHashEntryHdr struct nsRequestInfo : public PLDHashEntryHdr
{ {
nsRequestInfo(const void *key) nsRequestInfo(const void *key)
: mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(PR_FALSE) : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(PR_FALSE)
, mIsDone(PR_FALSE) , mLastStatus(nsnull)
{ {
MOZ_COUNT_CTOR(nsRequestInfo);
}
~nsRequestInfo()
{
MOZ_COUNT_DTOR(nsRequestInfo);
} }
nsIRequest* Request() { nsIRequest* Request() {
@ -111,9 +137,7 @@ struct nsRequestInfo : public PLDHashEntryHdr
PRInt64 mMaxProgress; PRInt64 mMaxProgress;
PRBool mUploading; PRBool mUploading;
PRBool mIsDone; nsAutoPtr<nsStatusInfo> mLastStatus;
nsString mLastStatus;
nsresult mLastStatusCode;
}; };
@ -186,6 +210,8 @@ nsDocLoader::nsDocLoader()
ClearInternalProgress(); ClearInternalProgress();
PR_INIT_CLIST(&mStatusInfoList);
PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: created.\n", this)); ("DocLoader:%p: created.\n", this));
} }
@ -601,7 +627,12 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
// //
nsRequestInfo *info = GetRequestInfo(aRequest); nsRequestInfo *info = GetRequestInfo(aRequest);
if (info) { if (info) {
info->mIsDone = PR_TRUE; if (info->mLastStatus) {
// Null it out now so we don't find it when looking for status
// from now on. This destroys the nsStatusInfo and hence
// removes it from our list.
info->mLastStatus = nsnull;
}
PRInt64 oldMax = info->mMaxProgress; PRInt64 oldMax = info->mMaxProgress;
@ -875,24 +906,6 @@ void nsDocLoader::doStartURLLoad(nsIRequest *request)
NS_OK); NS_OK);
} }
// PLDHashTable enumeration callback that finds a RequestInfo that's not done
// yet.
static PLDHashOperator
FindUnfinishedRequestCallback(PLDHashTable *table, PLDHashEntryHdr *hdr,
PRUint32 number, void *arg)
{
nsRequestInfo* info = static_cast<nsRequestInfo *>(hdr);
nsRequestInfo** retval = static_cast<nsRequestInfo**>(arg);
if (!info->mIsDone && !info->mLastStatus.IsEmpty()) {
*retval = info;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus) void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus)
{ {
#if defined(DEBUG) #if defined(DEBUG)
@ -911,15 +924,14 @@ void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus)
nsIWebProgressListener::STATE_IS_REQUEST, nsIWebProgressListener::STATE_IS_REQUEST,
aStatus); aStatus);
// Fire a status change message for a random unfinished request to make sure // Fire a status change message for the most recent unfinished
// that the displayed status is not outdated. // request to make sure that the displayed status is not outdated.
nsRequestInfo* unfinishedRequest = nsnull; if (!PR_CLIST_IS_EMPTY(&mStatusInfoList)) {
PL_DHashTableEnumerate(&mRequestInfoHash, FindUnfinishedRequestCallback, nsStatusInfo* statusInfo =
&unfinishedRequest); static_cast<nsStatusInfo*>(PR_LIST_HEAD(&mStatusInfoList));
if (unfinishedRequest) { FireOnStatusChange(this, statusInfo->mRequest,
FireOnStatusChange(this, unfinishedRequest->Request(), statusInfo->mStatusCode,
unfinishedRequest->mLastStatusCode, statusInfo->mStatusMessage.get());
unfinishedRequest->mLastStatus.get());
} }
} }
@ -1189,8 +1201,17 @@ NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
// don't display, for example, "Transferring" messages for requests that are // don't display, for example, "Transferring" messages for requests that are
// already done. // already done.
if (info) { if (info) {
info->mLastStatus = msg; if (!info->mLastStatus) {
info->mLastStatusCode = aStatus; info->mLastStatus = new nsStatusInfo(aRequest);
} else {
// We're going to move it to the front of the list, so remove
// it from wherever it is now.
PR_REMOVE_LINK(info->mLastStatus);
}
info->mLastStatus->mStatusMessage = msg;
info->mLastStatus->mStatusCode = aStatus;
// Put the info at the front of the list
PR_INSERT_LINK(info->mLastStatus, &mStatusInfoList);
} }
FireOnStatusChange(this, aRequest, aStatus, msg); FireOnStatusChange(this, aRequest, aStatus, msg);
} }

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

@ -59,6 +59,7 @@
#include "nsISupportsPriority.h" #include "nsISupportsPriority.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "pldhash.h" #include "pldhash.h"
#include "prclist.h"
struct nsRequestInfo; struct nsRequestInfo;
struct nsListenerInfo; struct nsListenerInfo;
@ -234,6 +235,8 @@ protected:
PLDHashTable mRequestInfoHash; PLDHashTable mRequestInfoHash;
PRInt64 mCompletedTotalProgress; PRInt64 mCompletedTotalProgress;
PRCList mStatusInfoList;
/* /*
* This flag indicates that the loader is loading a document. It is set * This flag indicates that the loader is loading a document. It is set
* from the call to LoadDocument(...) until the OnConnectionsComplete(...) * from the call to LoadDocument(...) until the OnConnectionsComplete(...)