forked from mirrors/gecko-dev
Bug 1805613 - Add a mutable status to WorkerRefs for logging. r=dom-worker-reviewers,asuth
In DEBUG mode, add a settable string to WorkerRefs. Record what we're doing in the XHR request worker, and log the status if we seem to be hanging (see WorkerPrivate::DumpCrashInformation). Differential Revision: https://phabricator.services.mozilla.com/D190054
This commit is contained in:
parent
04a070669d
commit
e756f1ac2f
6 changed files with 167 additions and 8 deletions
|
|
@ -5885,6 +5885,12 @@ void WorkerPrivate::DumpCrashInformation(nsACString& aString) {
|
||||||
if (workerRef->IsPreventingShutdown()) {
|
if (workerRef->IsPreventingShutdown()) {
|
||||||
aString.Append("|");
|
aString.Append("|");
|
||||||
aString.Append(workerRef->Name());
|
aString.Append(workerRef->Name());
|
||||||
|
const nsCString status = GET_WORKERREF_DEBUG_STATUS(workerRef);
|
||||||
|
if (!status.IsEmpty()) {
|
||||||
|
aString.Append("[");
|
||||||
|
aString.Append(status);
|
||||||
|
aString.Append("]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,11 @@ class ReleaseRefControlRunnable final : public WorkerControlRunnable {
|
||||||
|
|
||||||
WorkerRef::WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
WorkerRef::WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||||
bool aIsPreventingShutdown)
|
bool aIsPreventingShutdown)
|
||||||
: mWorkerPrivate(aWorkerPrivate),
|
:
|
||||||
|
#ifdef DEBUG
|
||||||
|
mDebugMutex("WorkerRef"),
|
||||||
|
#endif
|
||||||
|
mWorkerPrivate(aWorkerPrivate),
|
||||||
mName(aName),
|
mName(aName),
|
||||||
mIsPreventingShutdown(aIsPreventingShutdown),
|
mIsPreventingShutdown(aIsPreventingShutdown),
|
||||||
mHolding(false) {
|
mHolding(false) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@
|
||||||
#include "mozilla/MoveOnlyFunction.h"
|
#include "mozilla/MoveOnlyFunction.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
|
#include "nsTString.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
# include "mozilla/Mutex.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
||||||
|
|
@ -101,12 +106,37 @@ class WorkerPrivate;
|
||||||
class StrongWorkerRef;
|
class StrongWorkerRef;
|
||||||
class ThreadSafeWorkerRef;
|
class ThreadSafeWorkerRef;
|
||||||
|
|
||||||
|
#ifdef DEBUG // In debug mode, provide a way for clients to annotate WorkerRefs
|
||||||
|
# define SET_WORKERREF_DEBUG_STATUS(workerref, str) \
|
||||||
|
((workerref)->DebugSetWorkerRefStatus(str))
|
||||||
|
# define GET_WORKERREF_DEBUG_STATUS(workerref) \
|
||||||
|
((workerref)->DebugGetWorkerRefStatus())
|
||||||
|
#else
|
||||||
|
# define SET_WORKERREF_DEBUG_STATUS(workerref, str) (void())
|
||||||
|
# define GET_WORKERREF_DEBUG_STATUS(workerref) (EmptyCString())
|
||||||
|
#endif
|
||||||
|
|
||||||
class WorkerRef {
|
class WorkerRef {
|
||||||
friend class WorkerPrivate;
|
friend class WorkerPrivate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_INLINE_DECL_REFCOUNTING(WorkerRef)
|
NS_INLINE_DECL_REFCOUNTING(WorkerRef)
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
mutable Mutex mDebugMutex;
|
||||||
|
nsCString mDebugStatus MOZ_GUARDED_BY(mDebugMutex);
|
||||||
|
|
||||||
|
void DebugSetWorkerRefStatus(const nsCString& aStatus) {
|
||||||
|
MutexAutoLock lock(mDebugMutex);
|
||||||
|
mDebugStatus = aStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsCString DebugGetWorkerRefStatus() const {
|
||||||
|
MutexAutoLock lock(mDebugMutex);
|
||||||
|
return mDebugStatus;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
WorkerRef(WorkerPrivate* aWorkerPrivate, const char* aName,
|
||||||
bool aIsPreventingShutdown);
|
bool aIsPreventingShutdown);
|
||||||
|
|
@ -193,6 +223,10 @@ class ThreadSafeWorkerRef final {
|
||||||
|
|
||||||
WorkerPrivate* Private() const;
|
WorkerPrivate* Private() const;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
RefPtr<StrongWorkerRef>& Ref() { return mRef; }
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class StrongWorkerRef;
|
friend class StrongWorkerRef;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "mozilla/dom/FileCreatorHelper.h"
|
#include "mozilla/dom/FileCreatorHelper.h"
|
||||||
#include "mozilla/dom/FetchUtil.h"
|
#include "mozilla/dom/FetchUtil.h"
|
||||||
#include "mozilla/dom/FormData.h"
|
#include "mozilla/dom/FormData.h"
|
||||||
|
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||||
#include "mozilla/dom/MutableBlobStorage.h"
|
#include "mozilla/dom/MutableBlobStorage.h"
|
||||||
#include "mozilla/dom/XMLDocument.h"
|
#include "mozilla/dom/XMLDocument.h"
|
||||||
#include "mozilla/dom/URLSearchParams.h"
|
#include "mozilla/dom/URLSearchParams.h"
|
||||||
|
|
@ -184,6 +185,57 @@ static void AddLoadFlags(nsIRequest* request, nsLoadFlags newFlags) {
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
// In debug mode, annotate WorkerRefs with the name of the function being
|
||||||
|
// invoked for increased scrutability. Save the previous value on the stack.
|
||||||
|
namespace {
|
||||||
|
struct DebugWorkerRefs {
|
||||||
|
RefPtr<ThreadSafeWorkerRef>& mTSWorkerRef;
|
||||||
|
nsCString mPrev;
|
||||||
|
|
||||||
|
DebugWorkerRefs(RefPtr<ThreadSafeWorkerRef>& aTSWorkerRef,
|
||||||
|
const std::string& aStatus)
|
||||||
|
: mTSWorkerRef(aTSWorkerRef) {
|
||||||
|
if (!mTSWorkerRef) {
|
||||||
|
MOZ_LOG(gXMLHttpRequestLog, LogLevel::Info,
|
||||||
|
("No WorkerRef during: %s", aStatus.c_str()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mTSWorkerRef->Private());
|
||||||
|
|
||||||
|
nsCString status(aStatus.c_str());
|
||||||
|
mPrev = GET_WORKERREF_DEBUG_STATUS(mTSWorkerRef->Ref());
|
||||||
|
SET_WORKERREF_DEBUG_STATUS(mTSWorkerRef->Ref(), status);
|
||||||
|
}
|
||||||
|
|
||||||
|
~DebugWorkerRefs() {
|
||||||
|
if (!mTSWorkerRef) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(mTSWorkerRef->Private());
|
||||||
|
|
||||||
|
SET_WORKERREF_DEBUG_STATUS(mTSWorkerRef->Ref(), mPrev);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
# define STREAM_STRING(stuff) \
|
||||||
|
(((const std::ostringstream&)(std::ostringstream() << stuff)) \
|
||||||
|
.str()) // NOLINT
|
||||||
|
# define DEBUG_WORKERREFS \
|
||||||
|
DebugWorkerRefs MOZ_UNIQUE_VAR(debugWR__)(mTSWorkerRef, __func__)
|
||||||
|
# define DEBUG_WORKERREFS1(x) \
|
||||||
|
DebugWorkerRefs MOZ_UNIQUE_VAR(debugWR__)( \
|
||||||
|
mTSWorkerRef, STREAM_STRING(__func__ << ": " << x)) // NOLINT
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define DEBUG_WORKERREFS void()
|
||||||
|
# define DEBUG_WORKERREFS1(x) void()
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
bool XMLHttpRequestMainThread::sDontWarnAboutSyncXHR = false;
|
bool XMLHttpRequestMainThread::sDontWarnAboutSyncXHR = false;
|
||||||
|
|
||||||
XMLHttpRequestMainThread::XMLHttpRequestMainThread(
|
XMLHttpRequestMainThread::XMLHttpRequestMainThread(
|
||||||
|
|
@ -227,10 +279,12 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread(
|
||||||
mEventDispatchingSuspended(false),
|
mEventDispatchingSuspended(false),
|
||||||
mEofDecoded(false),
|
mEofDecoded(false),
|
||||||
mDelayedDoneNotifier(nullptr) {
|
mDelayedDoneNotifier(nullptr) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLHttpRequestMainThread::~XMLHttpRequestMainThread() {
|
XMLHttpRequestMainThread::~XMLHttpRequestMainThread() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(
|
MOZ_ASSERT(
|
||||||
!mDelayedDoneNotifier,
|
!mDelayedDoneNotifier,
|
||||||
"How can we have mDelayedDoneNotifier, which owns us, in destructor?");
|
"How can we have mDelayedDoneNotifier, which owns us, in destructor?");
|
||||||
|
|
@ -259,6 +313,7 @@ void XMLHttpRequestMainThread::Construct(
|
||||||
nsILoadGroup* aLoadGroup /* = nullptr */,
|
nsILoadGroup* aLoadGroup /* = nullptr */,
|
||||||
PerformanceStorage* aPerformanceStorage /* = nullptr */,
|
PerformanceStorage* aPerformanceStorage /* = nullptr */,
|
||||||
nsICSPEventListener* aCSPEventListener /* = nullptr */) {
|
nsICSPEventListener* aCSPEventListener /* = nullptr */) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(aPrincipal);
|
MOZ_ASSERT(aPrincipal);
|
||||||
mPrincipal = aPrincipal;
|
mPrincipal = aPrincipal;
|
||||||
mBaseURI = aBaseURI;
|
mBaseURI = aBaseURI;
|
||||||
|
|
@ -270,6 +325,7 @@ void XMLHttpRequestMainThread::Construct(
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::InitParameters(bool aAnon, bool aSystem) {
|
void XMLHttpRequestMainThread::InitParameters(bool aAnon, bool aSystem) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (!aAnon && !aSystem) {
|
if (!aAnon && !aSystem) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -461,6 +517,7 @@ Document* XMLHttpRequestMainThread::GetResponseXML(ErrorResult& aRv) {
|
||||||
* from HTTP headers.
|
* from HTTP headers.
|
||||||
*/
|
*/
|
||||||
nsresult XMLHttpRequestMainThread::DetectCharset() {
|
nsresult XMLHttpRequestMainThread::DetectCharset() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
mDecoder = nullptr;
|
mDecoder = nullptr;
|
||||||
|
|
||||||
if (mResponseType != XMLHttpRequestResponseType::_empty &&
|
if (mResponseType != XMLHttpRequestResponseType::_empty &&
|
||||||
|
|
@ -938,6 +995,7 @@ void XMLHttpRequestMainThread::GetStatusText(nsACString& aStatusText,
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::TerminateOngoingFetch(nsresult detail) {
|
void XMLHttpRequestMainThread::TerminateOngoingFetch(nsresult detail) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if ((mState == XMLHttpRequest_Binding::OPENED && mFlagSend) ||
|
if ((mState == XMLHttpRequest_Binding::OPENED && mFlagSend) ||
|
||||||
mState == XMLHttpRequest_Binding::HEADERS_RECEIVED ||
|
mState == XMLHttpRequest_Binding::HEADERS_RECEIVED ||
|
||||||
mState == XMLHttpRequest_Binding::LOADING) {
|
mState == XMLHttpRequest_Binding::LOADING) {
|
||||||
|
|
@ -949,6 +1007,7 @@ void XMLHttpRequestMainThread::TerminateOngoingFetch(nsresult detail) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::CloseRequest(nsresult detail) {
|
void XMLHttpRequestMainThread::CloseRequest(nsresult detail) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
mWaitingForOnStopRequest = false;
|
mWaitingForOnStopRequest = false;
|
||||||
mErrorLoad = ErrorType::eTerminated;
|
mErrorLoad = ErrorType::eTerminated;
|
||||||
mErrorLoadDetail = detail;
|
mErrorLoadDetail = detail;
|
||||||
|
|
@ -961,6 +1020,7 @@ void XMLHttpRequestMainThread::CloseRequest(nsresult detail) {
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::CloseRequestWithError(
|
void XMLHttpRequestMainThread::CloseRequestWithError(
|
||||||
const ProgressEventType aType) {
|
const ProgressEventType aType) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_LOG(
|
MOZ_LOG(
|
||||||
gXMLHttpRequestLog, LogLevel::Debug,
|
gXMLHttpRequestLog, LogLevel::Debug,
|
||||||
("%p CloseRequestWithError(%hhu)", this, static_cast<uint8_t>(aType)));
|
("%p CloseRequestWithError(%hhu)", this, static_cast<uint8_t>(aType)));
|
||||||
|
|
@ -1326,6 +1386,7 @@ nsresult XMLHttpRequestMainThread::FireReadystatechangeEvent() {
|
||||||
void XMLHttpRequestMainThread::DispatchProgressEvent(
|
void XMLHttpRequestMainThread::DispatchProgressEvent(
|
||||||
DOMEventTargetHelper* aTarget, const ProgressEventType aType,
|
DOMEventTargetHelper* aTarget, const ProgressEventType aType,
|
||||||
int64_t aLoaded, int64_t aTotal) {
|
int64_t aLoaded, int64_t aTotal) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
NS_ASSERTION(aTarget, "null target");
|
NS_ASSERTION(aTarget, "null target");
|
||||||
|
|
||||||
if (NS_FAILED(CheckCurrentGlobalCorrectness()) ||
|
if (NS_FAILED(CheckCurrentGlobalCorrectness()) ||
|
||||||
|
|
@ -1378,6 +1439,7 @@ void XMLHttpRequestMainThread::DispatchProgressEvent(
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::DispatchOrStoreEvent(
|
void XMLHttpRequestMainThread::DispatchOrStoreEvent(
|
||||||
DOMEventTargetHelper* aTarget, Event* aEvent) {
|
DOMEventTargetHelper* aTarget, Event* aEvent) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(aTarget);
|
MOZ_ASSERT(aTarget);
|
||||||
MOZ_ASSERT(aEvent);
|
MOZ_ASSERT(aEvent);
|
||||||
|
|
||||||
|
|
@ -1459,6 +1521,7 @@ void XMLHttpRequestMainThread::Open(const nsACString& aMethod,
|
||||||
const nsAString& aUsername,
|
const nsAString& aUsername,
|
||||||
const nsAString& aPassword,
|
const nsAString& aPassword,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
|
DEBUG_WORKERREFS1(aMethod << " " << aUrl);
|
||||||
NOT_CALLABLE_IN_SYNC_SEND_RV
|
NOT_CALLABLE_IN_SYNC_SEND_RV
|
||||||
|
|
||||||
// Gecko-specific
|
// Gecko-specific
|
||||||
|
|
@ -1817,6 +1880,7 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest* request,
|
||||||
nsIInputStream* inStr,
|
nsIInputStream* inStr,
|
||||||
uint64_t sourceOffset,
|
uint64_t sourceOffset,
|
||||||
uint32_t count) {
|
uint32_t count) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
NS_ENSURE_ARG_POINTER(inStr);
|
NS_ENSURE_ARG_POINTER(inStr);
|
||||||
|
|
||||||
mProgressSinceLastProgressEvent = true;
|
mProgressSinceLastProgressEvent = true;
|
||||||
|
|
@ -1885,6 +1949,7 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest* request,
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) {
|
XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStartRequest", NETWORK);
|
AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStartRequest", NETWORK);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
@ -2159,6 +2224,7 @@ XMLHttpRequestMainThread::OnStartRequest(nsIRequest* request) {
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request, nsresult status) {
|
XMLHttpRequestMainThread::OnStopRequest(nsIRequest* request, nsresult status) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStopRequest", NETWORK);
|
AUTO_PROFILER_LABEL("XMLHttpRequestMainThread::OnStopRequest", NETWORK);
|
||||||
|
|
||||||
if (request != mChannel) {
|
if (request != mChannel) {
|
||||||
|
|
@ -2386,6 +2452,7 @@ void XMLHttpRequestMainThread::MatchCharsetAndDecoderToResponseDocument() {
|
||||||
mDecoder = mResponseXML->GetDocumentCharacterSet()->NewDecoder();
|
mDecoder = mResponseXML->GetDocumentCharacterSet()->NewDecoder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::DisconnectDoneNotifier() {
|
void XMLHttpRequestMainThread::DisconnectDoneNotifier() {
|
||||||
if (mDelayedDoneNotifier) {
|
if (mDelayedDoneNotifier) {
|
||||||
// Disconnect may release the last reference to 'this'.
|
// Disconnect may release the last reference to 'this'.
|
||||||
|
|
@ -2396,6 +2463,7 @@ void XMLHttpRequestMainThread::DisconnectDoneNotifier() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::ChangeStateToDone(bool aWasSync) {
|
void XMLHttpRequestMainThread::ChangeStateToDone(bool aWasSync) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
DisconnectDoneNotifier();
|
DisconnectDoneNotifier();
|
||||||
|
|
||||||
if (!mForWorker && !aWasSync && mChannel) {
|
if (!mForWorker && !aWasSync && mChannel) {
|
||||||
|
|
@ -2422,6 +2490,7 @@ void XMLHttpRequestMainThread::ChangeStateToDone(bool aWasSync) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::ChangeStateToDoneInternal() {
|
void XMLHttpRequestMainThread::ChangeStateToDoneInternal() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
DisconnectDoneNotifier();
|
DisconnectDoneNotifier();
|
||||||
StopProgressEventTimer();
|
StopProgressEventTimer();
|
||||||
|
|
||||||
|
|
@ -2481,6 +2550,7 @@ void XMLHttpRequestMainThread::ChangeStateToDoneInternal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult XMLHttpRequestMainThread::CreateChannel() {
|
nsresult XMLHttpRequestMainThread::CreateChannel() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
// When we are called from JS we can find the load group for the page,
|
// When we are called from JS we can find the load group for the page,
|
||||||
// and add ourselves to it. This way any pending requests
|
// and add ourselves to it. This way any pending requests
|
||||||
// will be automatically aborted if the user leaves the page.
|
// will be automatically aborted if the user leaves the page.
|
||||||
|
|
@ -2606,6 +2676,7 @@ void XMLHttpRequestMainThread::MaybeLowerChannelPriority() {
|
||||||
nsresult XMLHttpRequestMainThread::InitiateFetch(
|
nsresult XMLHttpRequestMainThread::InitiateFetch(
|
||||||
already_AddRefed<nsIInputStream> aUploadStream, int64_t aUploadLength,
|
already_AddRefed<nsIInputStream> aUploadStream, int64_t aUploadLength,
|
||||||
nsACString& aUploadContentType) {
|
nsACString& aUploadContentType) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsIInputStream> uploadStream = std::move(aUploadStream);
|
nsCOMPtr<nsIInputStream> uploadStream = std::move(aUploadStream);
|
||||||
|
|
||||||
|
|
@ -2902,6 +2973,7 @@ void XMLHttpRequestMainThread::EnsureChannelContentType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::ResumeTimeout() {
|
void XMLHttpRequestMainThread::ResumeTimeout() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mFlagSynchronous);
|
MOZ_ASSERT(mFlagSynchronous);
|
||||||
|
|
||||||
|
|
@ -2916,6 +2988,7 @@ void XMLHttpRequestMainThread::Send(
|
||||||
DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
|
DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString>&
|
||||||
aData,
|
aData,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
|
DEBUG_WORKERREFS1(mRequestURL);
|
||||||
NOT_CALLABLE_IN_SYNC_SEND_RV
|
NOT_CALLABLE_IN_SYNC_SEND_RV
|
||||||
|
|
||||||
if (!CanSend(aRv)) {
|
if (!CanSend(aRv)) {
|
||||||
|
|
@ -3018,6 +3091,7 @@ bool XMLHttpRequestMainThread::CanSend(ErrorResult& aRv) {
|
||||||
void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
|
void XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody,
|
||||||
bool aBodyIsDocumentOrString,
|
bool aBodyIsDocumentOrString,
|
||||||
ErrorResult& aRv) {
|
ErrorResult& aRv) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
// We expect that CanSend has been called before we get here!
|
// We expect that CanSend has been called before we get here!
|
||||||
|
|
@ -3297,6 +3371,7 @@ nsIEventTarget* XMLHttpRequestMainThread::GetTimerEventTarget() {
|
||||||
|
|
||||||
nsresult XMLHttpRequestMainThread::DispatchToMainThread(
|
nsresult XMLHttpRequestMainThread::DispatchToMainThread(
|
||||||
already_AddRefed<nsIRunnable> aRunnable) {
|
already_AddRefed<nsIRunnable> aRunnable) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (nsIGlobalObject* global = GetOwnerGlobal()) {
|
if (nsIGlobalObject* global = GetOwnerGlobal()) {
|
||||||
return global->Dispatch(std::move(aRunnable));
|
return global->Dispatch(std::move(aRunnable));
|
||||||
}
|
}
|
||||||
|
|
@ -3304,6 +3379,7 @@ nsresult XMLHttpRequestMainThread::DispatchToMainThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::StartTimeoutTimer() {
|
void XMLHttpRequestMainThread::StartTimeoutTimer() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(
|
MOZ_ASSERT(
|
||||||
mRequestSentTime,
|
mRequestSentTime,
|
||||||
"StartTimeoutTimer mustn't be called before the request was sent!");
|
"StartTimeoutTimer mustn't be called before the request was sent!");
|
||||||
|
|
@ -3441,6 +3517,7 @@ NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::AsyncOnChannelRedirect(
|
XMLHttpRequestMainThread::AsyncOnChannelRedirect(
|
||||||
nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aFlags,
|
nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aFlags,
|
||||||
nsIAsyncVerifyRedirectCallback* callback) {
|
nsIAsyncVerifyRedirectCallback* callback) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(aNewChannel, "Redirect without a channel?");
|
MOZ_ASSERT(aNewChannel, "Redirect without a channel?");
|
||||||
|
|
||||||
// Prepare to receive callback
|
// Prepare to receive callback
|
||||||
|
|
@ -3472,6 +3549,7 @@ XMLHttpRequestMainThread::AsyncOnChannelRedirect(
|
||||||
|
|
||||||
nsresult XMLHttpRequestMainThread::OnRedirectVerifyCallback(nsresult result,
|
nsresult XMLHttpRequestMainThread::OnRedirectVerifyCallback(nsresult result,
|
||||||
bool aStripAuth) {
|
bool aStripAuth) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||||
|
|
||||||
|
|
@ -3514,6 +3592,7 @@ nsresult XMLHttpRequestMainThread::OnRedirectVerifyCallback(nsresult result,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::OnProgress(nsIRequest* aRequest, int64_t aProgress,
|
XMLHttpRequestMainThread::OnProgress(nsIRequest* aRequest, int64_t aProgress,
|
||||||
int64_t aProgressMax) {
|
int64_t aProgressMax) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
// When uploading, OnProgress reports also headers in aProgress and
|
// When uploading, OnProgress reports also headers in aProgress and
|
||||||
// aProgressMax. So, try to remove the headers, if possible.
|
// aProgressMax. So, try to remove the headers, if possible.
|
||||||
bool lengthComputable = (aProgressMax != -1);
|
bool lengthComputable = (aProgressMax != -1);
|
||||||
|
|
@ -3546,6 +3625,7 @@ XMLHttpRequestMainThread::OnProgress(nsIRequest* aRequest, int64_t aProgress,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::OnStatus(nsIRequest* aRequest, nsresult aStatus,
|
XMLHttpRequestMainThread::OnStatus(nsIRequest* aRequest, nsresult aStatus,
|
||||||
const char16_t* aStatusArg) {
|
const char16_t* aStatusArg) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (mProgressEventSink) {
|
if (mProgressEventSink) {
|
||||||
mProgressEventSink->OnStatus(aRequest, aStatus, aStatusArg);
|
mProgressEventSink->OnStatus(aRequest, aStatus, aStatusArg);
|
||||||
}
|
}
|
||||||
|
|
@ -3640,6 +3720,7 @@ bool XMLHttpRequestMainThread::MozAnon() const { return mIsAnon; }
|
||||||
bool XMLHttpRequestMainThread::MozSystem() const { return IsSystemXHR(); }
|
bool XMLHttpRequestMainThread::MozSystem() const { return IsSystemXHR(); }
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::HandleTimeoutCallback() {
|
void XMLHttpRequestMainThread::HandleTimeoutCallback() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (mState == XMLHttpRequest_Binding::DONE) {
|
if (mState == XMLHttpRequest_Binding::DONE) {
|
||||||
MOZ_ASSERT_UNREACHABLE(
|
MOZ_ASSERT_UNREACHABLE(
|
||||||
"XMLHttpRequestMainThread::HandleTimeoutCallback "
|
"XMLHttpRequestMainThread::HandleTimeoutCallback "
|
||||||
|
|
@ -3653,6 +3734,7 @@ void XMLHttpRequestMainThread::HandleTimeoutCallback() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::CancelTimeoutTimer() {
|
void XMLHttpRequestMainThread::CancelTimeoutTimer() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (mTimeoutTimer) {
|
if (mTimeoutTimer) {
|
||||||
mTimeoutTimer->Cancel();
|
mTimeoutTimer->Cancel();
|
||||||
mTimeoutTimer = nullptr;
|
mTimeoutTimer = nullptr;
|
||||||
|
|
@ -3661,6 +3743,7 @@ void XMLHttpRequestMainThread::CancelTimeoutTimer() {
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
XMLHttpRequestMainThread::Notify(nsITimer* aTimer) {
|
XMLHttpRequestMainThread::Notify(nsITimer* aTimer) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
if (mProgressNotifier == aTimer) {
|
if (mProgressNotifier == aTimer) {
|
||||||
HandleProgressTimerCallback();
|
HandleProgressTimerCallback();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -3683,6 +3766,7 @@ XMLHttpRequestMainThread::Notify(nsITimer* aTimer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::HandleProgressTimerCallback() {
|
void XMLHttpRequestMainThread::HandleProgressTimerCallback() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
// Don't fire the progress event if mLoadTotal is 0, see XHR spec step 6.1
|
// Don't fire the progress event if mLoadTotal is 0, see XHR spec step 6.1
|
||||||
if (!mLoadTotal && mLoadTransferred) {
|
if (!mLoadTotal && mLoadTransferred) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -3829,6 +3913,7 @@ XMLHttpRequestMainThread::nsHeaderVisitor::nsHeaderVisitor(
|
||||||
XMLHttpRequestMainThread::nsHeaderVisitor::~nsHeaderVisitor() = default;
|
XMLHttpRequestMainThread::nsHeaderVisitor::~nsHeaderVisitor() = default;
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::MaybeCreateBlobStorage() {
|
void XMLHttpRequestMainThread::MaybeCreateBlobStorage() {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
MOZ_ASSERT(mResponseType == XMLHttpRequestResponseType::Blob);
|
MOZ_ASSERT(mResponseType == XMLHttpRequestResponseType::Blob);
|
||||||
|
|
||||||
if (mBlobStorage) {
|
if (mBlobStorage) {
|
||||||
|
|
@ -3850,6 +3935,7 @@ void XMLHttpRequestMainThread::MaybeCreateBlobStorage() {
|
||||||
|
|
||||||
void XMLHttpRequestMainThread::BlobStoreCompleted(
|
void XMLHttpRequestMainThread::BlobStoreCompleted(
|
||||||
MutableBlobStorage* aBlobStorage, BlobImpl* aBlobImpl, nsresult aRv) {
|
MutableBlobStorage* aBlobStorage, BlobImpl* aBlobImpl, nsresult aRv) {
|
||||||
|
DEBUG_WORKERREFS;
|
||||||
// Ok, the state is changed...
|
// Ok, the state is changed...
|
||||||
if (mBlobStorage != aBlobStorage || NS_FAILED(aRv)) {
|
if (mBlobStorage != aBlobStorage || NS_FAILED(aRv)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#include "mozilla/dom/PerformanceStorage.h"
|
#include "mozilla/dom/PerformanceStorage.h"
|
||||||
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
#include "mozilla/dom/ServiceWorkerDescriptor.h"
|
||||||
#include "mozilla/dom/URLSearchParams.h"
|
#include "mozilla/dom/URLSearchParams.h"
|
||||||
|
#include "mozilla/dom/WorkerRef.h"
|
||||||
#include "mozilla/dom/XMLHttpRequest.h"
|
#include "mozilla/dom/XMLHttpRequest.h"
|
||||||
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
#include "mozilla/dom/XMLHttpRequestBinding.h"
|
||||||
#include "mozilla/dom/XMLHttpRequestEventTarget.h"
|
#include "mozilla/dom/XMLHttpRequestEventTarget.h"
|
||||||
|
|
@ -455,6 +456,11 @@ class XMLHttpRequestMainThread final : public XMLHttpRequest,
|
||||||
|
|
||||||
void LocalFileToBlobCompleted(BlobImpl* aBlobImpl);
|
void LocalFileToBlobCompleted(BlobImpl* aBlobImpl);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// For logging when there's trouble
|
||||||
|
RefPtr<ThreadSafeWorkerRef> mTSWorkerRef = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult DetectCharset();
|
nsresult DetectCharset();
|
||||||
nsresult AppendToResponseText(Span<const uint8_t> aBuffer,
|
nsresult AppendToResponseText(Span<const uint8_t> aBuffer,
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,11 @@
|
||||||
#include "nsIDOMEventListener.h"
|
#include "nsIDOMEventListener.h"
|
||||||
|
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "jsapi.h" // JS::RootedValueArray
|
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
#include "js/ArrayBuffer.h" // JS::Is{,Detached}ArrayBufferObject
|
#include "js/ArrayBuffer.h" // JS::Is{,Detached}ArrayBufferObject
|
||||||
#include "js/GCPolicyAPI.h"
|
#include "js/GCPolicyAPI.h"
|
||||||
#include "js/JSON.h"
|
#include "js/JSON.h"
|
||||||
#include "js/RootingAPI.h" // JS::{Handle,Heap},PersistentRooted
|
#include "js/RootingAPI.h" // JS::{Handle,Heap,PersistentRooted}
|
||||||
#include "js/TracingAPI.h"
|
#include "js/TracingAPI.h"
|
||||||
#include "js/Value.h" // JS::{Undefined,}Value
|
#include "js/Value.h" // JS::{Undefined,}Value
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
|
|
@ -193,6 +192,18 @@ class Proxy final : public nsIDOMEventListener {
|
||||||
return target.forget();
|
return target.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void DebugStoreWorkerRef(RefPtr<StrongWorkerRef>& aWorkerRef) {
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
mXHR->mTSWorkerRef = new ThreadSafeWorkerRef(aWorkerRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugForgetWorkerRef() {
|
||||||
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
mXHR->mTSWorkerRef = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~Proxy() {
|
~Proxy() {
|
||||||
MOZ_ASSERT(!mXHR);
|
MOZ_ASSERT(!mXHR);
|
||||||
|
|
@ -206,8 +217,8 @@ class WorkerThreadProxySyncRunnable : public WorkerMainThreadRunnable {
|
||||||
RefPtr<Proxy> mProxy;
|
RefPtr<Proxy> mProxy;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// mErrorCode is set on the main thread by MainThreadRun and it's used to at
|
// mErrorCode is set on the main thread by MainThreadRun and it's used at the
|
||||||
// the end of the Dispatch() to return the error code.
|
// end of the Dispatch() to return the error code.
|
||||||
nsresult mErrorCode;
|
nsresult mErrorCode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1486,6 +1497,10 @@ void XMLHttpRequestWorker::MaybePin(ErrorResult& aRv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mPinnedSelfRef = this;
|
mPinnedSelfRef = this;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
mProxy->DebugStoreWorkerRef(mWorkerRef);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void XMLHttpRequestWorker::MaybeDispatchPrematureAbortEvents(ErrorResult& aRv) {
|
void XMLHttpRequestWorker::MaybeDispatchPrematureAbortEvents(ErrorResult& aRv) {
|
||||||
|
|
@ -1609,6 +1624,14 @@ void XMLHttpRequestWorker::Unpin() {
|
||||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
|
|
||||||
MOZ_ASSERT(mWorkerRef, "Mismatched calls to Unpin!");
|
MOZ_ASSERT(mWorkerRef, "Mismatched calls to Unpin!");
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (mProxy) {
|
||||||
|
// The proxy will be gone if WorkerIsGoingAway
|
||||||
|
mProxy->DebugForgetWorkerRef();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mWorkerRef = nullptr;
|
mWorkerRef = nullptr;
|
||||||
|
|
||||||
mPinnedSelfRef = nullptr;
|
mPinnedSelfRef = nullptr;
|
||||||
|
|
@ -1841,7 +1864,7 @@ void XMLHttpRequestWorker::SetTimeout(uint32_t aTimeout, ErrorResult& aRv) {
|
||||||
mTimeout = aTimeout;
|
mTimeout = aTimeout;
|
||||||
|
|
||||||
if (!mProxy) {
|
if (!mProxy) {
|
||||||
// Open may not have been called yet, in which case we'll handle the
|
// Open might not have been called yet, in which case we'll handle the
|
||||||
// timeout in OpenRunnable.
|
// timeout in OpenRunnable.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1863,7 +1886,7 @@ void XMLHttpRequestWorker::SetWithCredentials(bool aWithCredentials,
|
||||||
mWithCredentials = aWithCredentials;
|
mWithCredentials = aWithCredentials;
|
||||||
|
|
||||||
if (!mProxy) {
|
if (!mProxy) {
|
||||||
// Open may not have been called yet, in which case we'll handle the
|
// Open might not have been called yet, in which case we'll handle the
|
||||||
// credentials in OpenRunnable.
|
// credentials in OpenRunnable.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1885,7 +1908,7 @@ void XMLHttpRequestWorker::SetMozBackgroundRequest(bool aBackgroundRequest,
|
||||||
mBackgroundRequest = aBackgroundRequest;
|
mBackgroundRequest = aBackgroundRequest;
|
||||||
|
|
||||||
if (!mProxy) {
|
if (!mProxy) {
|
||||||
// Open may not have been called yet, in which case we'll handle the
|
// Open might not have been called yet, in which case we'll handle the
|
||||||
// background request in OpenRunnable.
|
// background request in OpenRunnable.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue