--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -282,17 +282,18 @@ namespace {
class PrintErrorOnConsoleRunnable final : public WorkerMainThreadRunnable
{
public:
PrintErrorOnConsoleRunnable(WebSocketImpl* aImpl,
const char* aBundleURI,
const char16_t* aError,
const char16_t** aFormatStrings,
uint32_t aFormatStringsLen)
- : WorkerMainThreadRunnable(aImpl->mWorkerPrivate)
+ : WorkerMainThreadRunnable(aImpl->mWorkerPrivate,
+ NS_LITERAL_CSTRING("WebSocket :: print error on console"))
, mImpl(aImpl)
, mBundleURI(aBundleURI)
, mError(aError)
, mFormatStrings(aFormatStrings)
, mFormatStringsLen(aFormatStringsLen)
{ }
bool MainThreadRun() override
@@ -567,17 +568,18 @@ WebSocketImpl::FailConnection(uint16_t a
}
namespace {
class DisconnectInternalRunnable final : public WorkerMainThreadRunnable
{
public:
explicit DisconnectInternalRunnable(WebSocketImpl* aImpl)
- : WorkerMainThreadRunnable(aImpl->mWorkerPrivate)
+ : WorkerMainThreadRunnable(aImpl->mWorkerPrivate,
+ NS_LITERAL_CSTRING("WebSocket :: disconnect"))
, mImpl(aImpl)
{ }
bool MainThreadRun() override
{
mImpl->DisconnectInternal();
return true;
}
@@ -985,18 +987,19 @@ public:
private:
JSContext* mCx;
};
class WebSocketMainThreadRunnable : public WorkerMainThreadRunnable
{
public:
- WebSocketMainThreadRunnable(WorkerPrivate* aWorkerPrivate)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ WebSocketMainThreadRunnable(WorkerPrivate* aWorkerPrivate,
+ const nsACString& aTelemetryKey)
+ : WorkerMainThreadRunnable(aWorkerPrivate, aTelemetryKey)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
}
bool MainThreadRun() override
{
AssertIsOnMainThread();
@@ -1024,17 +1027,18 @@ protected:
class InitRunnable final : public WebSocketMainThreadRunnable
{
public:
InitRunnable(WebSocketImpl* aImpl, const nsAString& aURL,
nsTArray<nsString>& aProtocolArray,
const nsACString& aScriptFile, uint32_t aScriptLine,
uint32_t aScriptColumn,
ErrorResult& aRv, bool* aConnectionFailed)
- : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate)
+ : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
+ NS_LITERAL_CSTRING("WebSocket :: init"))
, mImpl(aImpl)
, mURL(aURL)
, mProtocolArray(aProtocolArray)
, mScriptFile(aScriptFile)
, mScriptLine(aScriptLine)
, mScriptColumn(aScriptColumn)
, mRv(aRv)
, mConnectionFailed(aConnectionFailed)
@@ -1093,17 +1097,18 @@ protected:
ErrorResult& mRv;
bool* mConnectionFailed;
};
class AsyncOpenRunnable final : public WebSocketMainThreadRunnable
{
public:
AsyncOpenRunnable(WebSocketImpl* aImpl, ErrorResult& aRv)
- : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate)
+ : WebSocketMainThreadRunnable(aImpl->mWorkerPrivate,
+ NS_LITERAL_CSTRING("WebSocket :: AsyncOpen"))
, mImpl(aImpl)
, mRv(aRv)
{
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->AssertIsOnWorkerThread();
}
protected:
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -68,17 +68,18 @@ GetPrincipalFromWorkerPrivate(WorkerPriv
}
class InitializeRunnable final : public WorkerMainThreadRunnable
{
public:
InitializeRunnable(WorkerPrivate* aWorkerPrivate, nsACString& aOrigin,
PrincipalInfo& aPrincipalInfo, bool& aPrivateBrowsing,
ErrorResult& aRv)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("BroadcastChannel :: Initialize"))
, mWorkerPrivate(GetCurrentThreadWorkerPrivate())
, mOrigin(aOrigin)
, mPrincipalInfo(aPrincipalInfo)
, mPrivateBrowsing(aPrivateBrowsing)
, mRv(aRv)
{
MOZ_ASSERT(mWorkerPrivate);
}
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -264,17 +264,18 @@ class CreateImageFromRawDataInMainThread
public:
CreateImageFromRawDataInMainThreadSyncTask(uint8_t* aBuffer,
uint32_t aBufferLength,
uint32_t aStride,
gfx::SurfaceFormat aFormat,
const gfx::IntSize& aSize,
const Maybe<IntRect>& aCropRect,
layers::Image** aImage)
- : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate())
+ : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
+ NS_LITERAL_CSTRING("ImageBitmap :: Create Image from Raw Data"))
, mImage(aImage)
, mBuffer(aBuffer)
, mBufferLength(aBufferLength)
, mStride(aStride)
, mFormat(aFormat)
, mSize(aSize)
, mCropRect(aCropRect)
{
@@ -1145,17 +1146,18 @@ class CreateImageBitmapFromBlobWorkerTas
// This is a synchronous task.
class DecodeBlobInMainThreadSyncTask final : public WorkerMainThreadRunnable
{
public:
DecodeBlobInMainThreadSyncTask(WorkerPrivate* aWorkerPrivate,
Blob& aBlob,
Maybe<IntRect>& aCropRect,
layers::Image** aImage)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("ImageBitmap :: Create Image from Blob"))
, mBlob(aBlob)
, mCropRect(aCropRect)
, mImage(aImage)
{
}
bool MainThreadRun() override
{
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -713,17 +713,18 @@ public:
};
template <class Derived>
class CancelPumpRunnable final : public WorkerMainThreadRunnable
{
FetchBody<Derived>* mBody;
public:
explicit CancelPumpRunnable(FetchBody<Derived>* aBody)
- : WorkerMainThreadRunnable(aBody->mWorkerPrivate)
+ : WorkerMainThreadRunnable(aBody->mWorkerPrivate,
+ NS_LITERAL_CSTRING("Fetch :: Cancel Pump"))
, mBody(aBody)
{ }
bool
MainThreadRun() override
{
mBody->CancelPump();
return true;
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -226,17 +226,18 @@ GetRequestURLFromWorker(const GlobalObje
}
class ReferrerSameOriginChecker final : public workers::WorkerMainThreadRunnable
{
public:
ReferrerSameOriginChecker(workers::WorkerPrivate* aWorkerPrivate,
const nsAString& aReferrerURL,
nsresult& aResult)
- : workers::WorkerMainThreadRunnable(aWorkerPrivate),
+ : workers::WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("Fetch :: Referrer same origin check")),
mReferrerURL(aReferrerURL),
mResult(aResult)
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
bool
MainThreadRun() override
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -284,17 +284,18 @@ public:
};
class GetPermissionRunnable final : public WorkerMainThreadRunnable
{
NotificationPermission mPermission;
public:
explicit GetPermissionRunnable(WorkerPrivate* aWorker)
- : WorkerMainThreadRunnable(aWorker)
+ : WorkerMainThreadRunnable(aWorker,
+ NS_LITERAL_CSTRING("Notification :: Get Permission"))
, mPermission(NotificationPermission::Denied)
{ }
bool
MainThreadRun() override
{
ErrorResult result;
mPermission =
@@ -2443,17 +2444,18 @@ NotificationFeature::NotificationFeature
class CloseNotificationRunnable final
: public WorkerMainThreadRunnable
{
Notification* mNotification;
bool mHadObserver;
public:
explicit CloseNotificationRunnable(Notification* aNotification)
- : WorkerMainThreadRunnable(aNotification->mWorkerPrivate)
+ : WorkerMainThreadRunnable(aNotification->mWorkerPrivate,
+ NS_LITERAL_CSTRING("Notification :: Close Notification"))
, mNotification(aNotification)
, mHadObserver(false)
{}
bool
MainThreadRun() override
{
if (mNotification->mObserver) {
@@ -2550,17 +2552,18 @@ Notification::UnregisterFeature()
*/
class CheckLoadRunnable final : public WorkerMainThreadRunnable
{
nsresult mRv;
nsCString mScope;
public:
explicit CheckLoadRunnable(WorkerPrivate* aWorker, const nsACString& aScope)
- : WorkerMainThreadRunnable(aWorker)
+ : WorkerMainThreadRunnable(aWorker,
+ NS_LITERAL_CSTRING("Notification :: Check Load"))
, mRv(NS_ERROR_DOM_SECURITY_ERR)
, mScope(aScope)
{ }
bool
MainThreadRun() override
{
nsIPrincipal* principal = mWorkerPrivate->GetPrincipal();
--- a/dom/workers/ServiceWorkerRegistration.cpp
+++ b/dom/workers/ServiceWorkerRegistration.cpp
@@ -1074,17 +1074,18 @@ public:
};
class SyncStopListeningRunnable final : public WorkerMainThreadRunnable
{
RefPtr<WorkerListener> mListener;
public:
SyncStopListeningRunnable(WorkerPrivate* aWorkerPrivate,
WorkerListener* aListener)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("ServiceWorkerRegistration :: StopListening"))
, mListener(aListener)
{}
bool
MainThreadRun() override
{
mListener->StopListeningForEvents();
return true;
--- a/dom/workers/URL.cpp
+++ b/dom/workers/URL.cpp
@@ -72,17 +72,18 @@ class CreateURLRunnable : public WorkerM
private:
BlobImpl* mBlobImpl;
nsAString& mURL;
public:
CreateURLRunnable(WorkerPrivate* aWorkerPrivate, BlobImpl* aBlobImpl,
const mozilla::dom::objectURLOptions& aOptions,
nsAString& aURL)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("URL :: CreateURL"))
, mBlobImpl(aBlobImpl)
, mURL(aURL)
{
MOZ_ASSERT(aBlobImpl);
DebugOnly<bool> isMutable;
MOZ_ASSERT(NS_SUCCEEDED(aBlobImpl->GetMutable(&isMutable)));
MOZ_ASSERT(!isMutable);
@@ -163,17 +164,18 @@ public:
class RevokeURLRunnable : public WorkerMainThreadRunnable
{
private:
const nsString mURL;
public:
RevokeURLRunnable(WorkerPrivate* aWorkerPrivate,
const nsAString& aURL)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("URL :: RevokeURL"))
, mURL(aURL)
{}
bool
MainThreadRun()
{
AssertIsOnMainThread();
@@ -224,32 +226,34 @@ private:
mozilla::ErrorResult& mRv;
RefPtr<URLProxy> mRetval;
public:
ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
const nsAString& aURL, const Optional<nsAString>& aBase,
mozilla::ErrorResult& aRv)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("URL :: Constructor"))
, mURL(aURL)
, mRv(aRv)
{
if (aBase.WasPassed()) {
mBase = aBase.Value();
} else {
mBase.SetIsVoid(true);
}
mWorkerPrivate->AssertIsOnWorkerThread();
}
ConstructorRunnable(WorkerPrivate* aWorkerPrivate,
const nsAString& aURL, URLProxy* aBaseProxy,
mozilla::ErrorResult& aRv)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("URL :: Constructor with BaseURL"))
, mURL(aURL)
, mBaseProxy(aBaseProxy)
, mRv(aRv)
{
mBase.SetIsVoid(true);
mWorkerPrivate->AssertIsOnWorkerThread();
}
@@ -321,17 +325,20 @@ public:
GetterPathname,
GetterSearch,
GetterHash,
};
GetterRunnable(WorkerPrivate* aWorkerPrivate,
GetterType aType, nsAString& aValue,
URLProxy* aURLProxy)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ // We can have telemetry keys for each getter when
+ // needed.
+ NS_LITERAL_CSTRING("URL :: getter"))
, mValue(aValue)
, mType(aType)
, mURLProxy(aURLProxy)
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
bool
@@ -409,17 +416,20 @@ public:
SetterPathname,
SetterSearch,
SetterHash,
};
SetterRunnable(WorkerPrivate* aWorkerPrivate,
SetterType aType, const nsAString& aValue,
URLProxy* aURLProxy)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ // We can have telemetry keys for each setter when
+ // needed.
+ NS_LITERAL_CSTRING("URL :: setter"))
, mValue(aValue)
, mType(aType)
, mURLProxy(aURLProxy)
, mFailed(false)
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
--- a/dom/workers/WorkerNavigator.cpp
+++ b/dom/workers/WorkerNavigator.cpp
@@ -104,17 +104,18 @@ WorkerNavigator::GetPlatform(nsString& a
namespace {
class GetUserAgentRunnable final : public WorkerMainThreadRunnable
{
nsString& mUA;
public:
GetUserAgentRunnable(WorkerPrivate* aWorkerPrivate, nsString& aUA)
- : WorkerMainThreadRunnable(aWorkerPrivate)
+ : WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("UserAgent getter"))
, mUA(aUA)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
}
virtual bool MainThreadRun() override
{
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -10,16 +10,17 @@
#include "nsIEventTarget.h"
#include "nsIGlobalObject.h"
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/Telemetry.h"
#include "js/RootingAPI.h"
#include "js/Value.h"
#include "WorkerPrivate.h"
#include "WorkerScope.h"
USING_WORKERS_NAMESPACE
@@ -567,40 +568,48 @@ void
MainThreadWorkerControlRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
AssertIsOnMainThread();
}
NS_IMPL_ISUPPORTS_INHERITED0(WorkerControlRunnable, WorkerRunnable)
-WorkerMainThreadRunnable::WorkerMainThreadRunnable(WorkerPrivate* aWorkerPrivate)
+WorkerMainThreadRunnable::WorkerMainThreadRunnable(WorkerPrivate* aWorkerPrivate,
+ const nsACString& aTelemetryKey)
: mWorkerPrivate(aWorkerPrivate)
+, mTelemetryKey(aTelemetryKey)
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
void
WorkerMainThreadRunnable::Dispatch(ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
+ TimeStamp startTime = TimeStamp::NowLoRes();
+
AutoSyncLoopHolder syncLoop(mWorkerPrivate);
mSyncLoopTarget = syncLoop.EventTarget();
RefPtr<WorkerMainThreadRunnable> runnable(this);
DebugOnly<nsresult> rv =
NS_DispatchToMainThread(runnable.forget(), NS_DISPATCH_NORMAL);
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Should only fail after xpcom-shutdown-threads and we're gone by then");
if (!syncLoop.Run()) {
aRv.ThrowUncatchableException();
}
+
+ Telemetry::Accumulate(Telemetry::SYNC_WORKER_OPERATION, mTelemetryKey,
+ static_cast<uint32_t>((TimeStamp::NowLoRes() - startTime)
+ .ToMilliseconds()));
}
NS_IMETHODIMP
WorkerMainThreadRunnable::Run()
{
AssertIsOnMainThread();
bool runResult = MainThreadRun();
@@ -610,16 +619,24 @@ WorkerMainThreadRunnable::Run()
mSyncLoopTarget.forget(),
runResult);
MOZ_ALWAYS_TRUE(response->Dispatch());
return NS_OK;
}
+WorkerCheckAPIExposureOnMainThreadRunnable::WorkerCheckAPIExposureOnMainThreadRunnable(WorkerPrivate* aWorkerPrivate):
+ WorkerMainThreadRunnable(aWorkerPrivate,
+ NS_LITERAL_CSTRING("WorkerCheckAPIExposureOnMainThread"))
+{}
+
+WorkerCheckAPIExposureOnMainThreadRunnable::~WorkerCheckAPIExposureOnMainThreadRunnable()
+{}
+
bool
WorkerCheckAPIExposureOnMainThreadRunnable::Dispatch()
{
ErrorResult rv;
WorkerMainThreadRunnable::Dispatch(rv);
bool ok = !rv.Failed();
rv.SuppressException();
return ok;
--- a/dom/workers/WorkerRunnable.h
+++ b/dom/workers/WorkerRunnable.h
@@ -424,18 +424,20 @@ protected:
// dispatch the tasks from the worker thread to the main thread.
//
// Note that the derived class must override MainThreadRun.
class WorkerMainThreadRunnable : public Runnable
{
protected:
WorkerPrivate* mWorkerPrivate;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
+ const nsCString mTelemetryKey;
- explicit WorkerMainThreadRunnable(WorkerPrivate* aWorkerPrivate);
+ explicit WorkerMainThreadRunnable(WorkerPrivate* aWorkerPrivate,
+ const nsACString& aTelemetryKey);
~WorkerMainThreadRunnable() {}
virtual bool MainThreadRun() = 0;
public:
// Dispatch the runnable to the main thread. If dispatch to main thread
// fails, or if the worker is shut down while dispatching, an error will be
// reported on aRv. In that case the error MUST be propagated out to script.
@@ -447,23 +449,24 @@ private:
// Class for checking API exposure. This totally violates the "MUST" in the
// comments on WorkerMainThreadRunnable::Dispatch, because API exposure checks
// can't throw. Maybe we should change it so they _could_ throw. But for now
// we are bad people and should be ashamed of ourselves. Let's hope none of
// them happen while a worker is shutting down.
//
// Do NOT copy what this class is doing elsewhere. Just don't.
-class WorkerCheckAPIExposureOnMainThreadRunnable : public WorkerMainThreadRunnable
+class WorkerCheckAPIExposureOnMainThreadRunnable
+ : public WorkerMainThreadRunnable
{
public:
- explicit WorkerCheckAPIExposureOnMainThreadRunnable(WorkerPrivate* aWorkerPrivate):
- WorkerMainThreadRunnable(aWorkerPrivate)
- {}
- ~WorkerCheckAPIExposureOnMainThreadRunnable() {}
+ explicit
+ WorkerCheckAPIExposureOnMainThreadRunnable(WorkerPrivate* aWorkerPrivate);
+ virtual
+ ~WorkerCheckAPIExposureOnMainThreadRunnable();
// Returns whether the dispatch succeeded. If this returns false, the API
// should not be exposed.
bool Dispatch();
};
END_WORKERS_NAMESPACE
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1496,17 +1496,18 @@ gfxUtils::GetInputStream(gfx::DataSource
class GetFeatureStatusRunnable final : public dom::workers::WorkerMainThreadRunnable
{
public:
GetFeatureStatusRunnable(dom::workers::WorkerPrivate* workerPrivate,
const nsCOMPtr<nsIGfxInfo>& gfxInfo,
int32_t feature,
nsACString& failureId,
int32_t* status)
- : WorkerMainThreadRunnable(workerPrivate)
+ : WorkerMainThreadRunnable(workerPrivate,
+ NS_LITERAL_CSTRING("GFX :: GetFeatureStatus"))
, mGfxInfo(gfxInfo)
, mFeature(feature)
, mStatus(status)
, mFailureId(failureId)
, mNSResult(NS_OK)
{
}
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -10595,10 +10595,20 @@
"description": "Measures the size of message manager messages by message name"
},
"SANDBOX_BROKER_INITIALIZED": {
"alert_emails": ["bowen@mozilla.com"],
"bug_numbers": [1256992],
"expires_in_version": "55",
"kind": "boolean",
"description": "Result of call to SandboxBroker::Initialize"
+ },
+ "SYNC_WORKER_OPERATION": {
+ "alert_emails": ["amarchesini@mozilla.com", "khuey@mozilla.com" ],
+ "bug_numbers": [1267904],
+ "expires_in_version": "never",
+ "kind": "exponential",
+ "high": 5000,
+ "n_buckets": 20,
+ "keyed": true,
+ "description": "Tracking how long a Worker thread is blocked when a sync operation is executed on the main-thread."
}
}