Bug 1647133 - P3. Use nsISerialEventTarget where it's actually that. r=valentin

All uses are always the main thread and its derivative (obtained via EventTargetFor method) or nullptr.

Depends on D80421

Differential Revision: https://phabricator.services.mozilla.com/D80422
This commit is contained in:
Jean-Yves Avenard 2020-06-22 11:13:24 +00:00
Родитель f89a18bd12
Коммит 4f53bc5dc3
18 изменённых файлов: 75 добавлений и 67 удалений

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

@ -5,7 +5,7 @@
#include "StunAddrsRequestChild.h"
#include "mozilla/net/NeckoChild.h"
#include "nsIEventTarget.h"
#include "nsISerialEventTarget.h"
using namespace mozilla::ipc;
@ -13,7 +13,7 @@ namespace mozilla {
namespace net {
StunAddrsRequestChild::StunAddrsRequestChild(
StunAddrsListener* listener, nsIEventTarget* mainThreadEventTarget)
StunAddrsListener* listener, nsISerialEventTarget* mainThreadEventTarget)
: mListener(listener) {
if (mainThreadEventTarget) {
gNeckoChild->SetEventTargetForActor(this, mainThreadEventTarget);

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

@ -7,7 +7,7 @@
#include "mozilla/net/PStunAddrsRequestChild.h"
class nsIEventTarget;
class nsISerialEventTarget;
namespace mozilla {
namespace net {
@ -33,7 +33,7 @@ class StunAddrsRequestChild final : public PStunAddrsRequestChild {
public:
explicit StunAddrsRequestChild(StunAddrsListener* listener,
nsIEventTarget* mainThreadEventTarget);
nsISerialEventTarget* mainThreadEventTarget);
NS_IMETHOD_(MozExternalRefCountType) AddRef();
NS_IMETHOD_(MozExternalRefCountType) Release();

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

@ -83,12 +83,12 @@ void WebrtcTCPSocketChild::AsyncOpen(
if (IsNeckoChild()) {
// We're on a content process
gNeckoChild->SetEventTargetForActor(this, GetMainThreadEventTarget());
gNeckoChild->SetEventTargetForActor(this, GetMainThreadSerialEventTarget());
gNeckoChild->SendPWebrtcTCPSocketConstructor(this, tabId);
} else if (IsSocketProcessChild()) {
// We're on a socket process
SocketProcessChild::GetSingleton()->SetEventTargetForActor(
this, GetMainThreadEventTarget());
this, GetMainThreadSerialEventTarget());
SocketProcessChild::GetSingleton()->SendPWebrtcTCPSocketConstructor(this,
tabId);
}

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

@ -13,7 +13,7 @@ interface nsIProtocolProxyChannelFilter;
interface nsIProxyInfo;
interface nsIChannel;
interface nsIURI;
interface nsIEventTarget;
interface nsISerialEventTarget;
/**
* nsIProtocolProxyService provides methods to access information about
@ -101,9 +101,10 @@ interface nsIProtocolProxyService : nsISupports
*
* @see nsIProxiedProtocolHandler::newProxiedChannel
*/
nsICancelable asyncResolve(in nsISupports aChannelOrURI, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback,
[optional] in nsIEventTarget aMainThreadTarget);
nsICancelable asyncResolve(
in nsISupports aChannelOrURI, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback,
[optional] in nsISerialEventTarget aMainThreadTarget);
/**
* This method may be called to construct a nsIProxyInfo instance from

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

@ -25,7 +25,8 @@ interface nsIProtocolProxyService2 : nsIProtocolProxyService
* of asyncResolve2()) if it is immediately ready to run.
* The nsICancelable return value will be null in that case.
*/
nsICancelable asyncResolve2(in nsIChannel aChannel, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback,
[optional] in nsIEventTarget aMainThreadTarget);
nsICancelable asyncResolve2(
in nsIChannel aChannel, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback,
[optional] in nsISerialEventTarget aMainThreadTarget);
};

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

@ -355,7 +355,7 @@ static uint32_t sThreadLocalIndex = 0xdeadbeef; // out of range
static const char* kPACIncludePath =
"network.proxy.autoconfig_url.include_path";
nsPACMan::nsPACMan(nsIEventTarget* mainThreadEventTarget)
nsPACMan::nsPACMan(nsISerialEventTarget* mainThreadEventTarget)
: NeckoTargetHolder(mainThreadEventTarget),
mLoadPending(false),
mShutdown(false),

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

@ -92,7 +92,7 @@ class nsPACMan final : public nsIStreamLoaderObserver,
public:
NS_DECL_THREADSAFE_ISUPPORTS
explicit nsPACMan(nsIEventTarget* mainThreadEventTarget);
explicit nsPACMan(nsISerialEventTarget* mainThreadEventTarget);
/**
* This method may be called to shutdown the PAC manager. Any async queries

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

@ -225,7 +225,7 @@ class nsAsyncResolveRequest final : public nsIRunnable,
nsCOMPtr<nsIProxyInfo> mProxyInfo;
// The logic is written as non-thread safe, assert single-thread usage.
nsCOMPtr<nsIEventTarget> mProcessingThread;
nsCOMPtr<nsISerialEventTarget> mProcessingThread;
};
void EnsureResolveFlagsMatch() {
@ -1352,7 +1352,7 @@ bool nsProtocolProxyService::IsProxyDisabled(nsProxyInfo* pi) {
}
nsresult nsProtocolProxyService::SetupPACThread(
nsIEventTarget* mainThreadEventTarget) {
nsISerialEventTarget* mainThreadEventTarget) {
if (mIsShutdown) {
return NS_ERROR_FAILURE;
}
@ -1505,7 +1505,7 @@ NS_IMPL_ISUPPORTS0(nsAsyncBridgeRequest)
nsresult nsProtocolProxyService::AsyncResolveInternal(
nsIChannel* channel, uint32_t flags, nsIProtocolProxyCallback* callback,
nsICancelable** result, bool isSyncOK,
nsIEventTarget* mainThreadEventTarget) {
nsISerialEventTarget* mainThreadEventTarget) {
NS_ENSURE_ARG_POINTER(channel);
NS_ENSURE_ARG_POINTER(callback);
@ -1564,19 +1564,18 @@ nsresult nsProtocolProxyService::AsyncResolveInternal(
// nsIProtocolProxyService
NS_IMETHODIMP
nsProtocolProxyService::AsyncResolve2(nsIChannel* channel, uint32_t flags,
nsIProtocolProxyCallback* callback,
nsIEventTarget* mainThreadEventTarget,
nsICancelable** result) {
nsProtocolProxyService::AsyncResolve2(
nsIChannel* channel, uint32_t flags, nsIProtocolProxyCallback* callback,
nsISerialEventTarget* mainThreadEventTarget, nsICancelable** result) {
return AsyncResolveInternal(channel, flags, callback, result, true,
mainThreadEventTarget);
}
NS_IMETHODIMP
nsProtocolProxyService::AsyncResolve(nsISupports* channelOrURI, uint32_t flags,
nsIProtocolProxyCallback* callback,
nsIEventTarget* mainThreadEventTarget,
nsICancelable** result) {
nsProtocolProxyService::AsyncResolve(
nsISupports* channelOrURI, uint32_t flags,
nsIProtocolProxyCallback* callback,
nsISerialEventTarget* mainThreadEventTarget, nsICancelable** result) {
nsresult rv;
// Check if we got a channel:
nsCOMPtr<nsIChannel> channel = do_QueryInterface(channelOrURI);

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

@ -310,7 +310,8 @@ class nsProtocolProxyService final : public nsIProtocolProxyService2,
void MaybeDisableDNSPrefetch(nsIProxyInfo* aProxy);
private:
nsresult SetupPACThread(nsIEventTarget* mainThreadEventTarget = nullptr);
nsresult SetupPACThread(
nsISerialEventTarget* mainThreadEventTarget = nullptr);
nsresult ResetPACThread();
nsresult ReloadNetworkPAC();
@ -400,9 +401,9 @@ class nsProtocolProxyService final : public nsIProtocolProxyService2,
nsresult AsyncResolveInternal(nsIChannel* channel, uint32_t flags,
nsIProtocolProxyCallback* callback,
nsICancelable** result, bool isSyncOK,
nsIEventTarget* mainThreadEventTarget);
nsISerialEventTarget* mainThreadEventTarget);
bool mIsShutdown;
nsCOMPtr<nsIEventTarget> mProxySettingTarget;
nsCOMPtr<nsISerialEventTarget> mProxySettingTarget;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService,

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

@ -173,7 +173,7 @@ bool NeckoChild::DeallocPWebSocketChild(PWebSocketChild* child) {
PWebSocketEventListenerChild* NeckoChild::AllocPWebSocketEventListenerChild(
const uint64_t& aInnerWindowID) {
nsCOMPtr<nsIEventTarget> target;
nsCOMPtr<nsISerialEventTarget> target;
if (nsGlobalWindowInner* win =
nsGlobalWindowInner::GetInnerWindowWithId(aInnerWindowID)) {
target = win->EventTargetFor(TaskCategory::Other);

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

@ -12,11 +12,11 @@
namespace mozilla {
namespace net {
already_AddRefed<nsIEventTarget> NeckoTargetHolder::GetNeckoTarget() {
nsCOMPtr<nsIEventTarget> target = mNeckoTarget;
already_AddRefed<nsISerialEventTarget> NeckoTargetHolder::GetNeckoTarget() {
nsCOMPtr<nsISerialEventTarget> target = mNeckoTarget;
if (!target) {
target = GetMainThreadEventTarget();
target = GetMainThreadSerialEventTarget();
}
return target.forget();
}
@ -27,7 +27,8 @@ nsresult NeckoTargetHolder::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable,
return mNeckoTarget->Dispatch(std::move(aRunnable), aDispatchFlags);
}
nsCOMPtr<nsIEventTarget> mainThreadTarget = GetMainThreadEventTarget();
nsCOMPtr<nsISerialEventTarget> mainThreadTarget =
GetMainThreadSerialEventTarget();
MOZ_ASSERT(mainThreadTarget);
return mainThreadTarget->Dispatch(std::move(aRunnable), aDispatchFlags);

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

@ -18,20 +18,20 @@ namespace net {
// channels should inherit this class in order to get a labeled event target.
class NeckoTargetHolder {
public:
explicit NeckoTargetHolder(nsIEventTarget* aNeckoTarget)
explicit NeckoTargetHolder(nsISerialEventTarget* aNeckoTarget)
: mNeckoTarget(aNeckoTarget) {}
protected:
virtual ~NeckoTargetHolder() = default;
// Get event target for processing network events.
virtual already_AddRefed<nsIEventTarget> GetNeckoTarget();
virtual already_AddRefed<nsISerialEventTarget> GetNeckoTarget();
// When |mNeckoTarget| is not null, use it to dispatch the runnable.
// Otherwise, dispatch the runnable to the main thread.
nsresult Dispatch(already_AddRefed<nsIRunnable>&& aRunnable,
uint32_t aDispatchFlags = NS_DISPATCH_NORMAL);
// EventTarget for labeling networking events.
nsCOMPtr<nsIEventTarget> mNeckoTarget;
nsCOMPtr<nsISerialEventTarget> mNeckoTarget;
};
} // namespace net

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

@ -53,8 +53,8 @@
#include "nsICompressConvStats.h"
#include "nsIDeprecationWarner.h"
#include "mozilla/dom/Document.h"
#include "nsIEventTarget.h"
#include "nsIScriptError.h"
#include "nsISerialEventTarget.h"
#include "nsRedirectHistoryEntry.h"
#include "nsSocketTransportService2.h"
#include "nsStreamUtils.h"
@ -375,7 +375,7 @@ void HttpChannelChild::OnBackgroundChildDestroyed(
}
if (callback) {
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
neckoTarget->Dispatch(callback, NS_DISPATCH_NORMAL);
}
}
@ -832,7 +832,7 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
DoOnProgress(this, progress, progressMax);
} else {
RefPtr<HttpChannelChild> self = this;
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
DebugOnly<nsresult> rv = neckoTarget->Dispatch(
@ -876,7 +876,7 @@ void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
// PHttpChannel connects to the main thread
RefPtr<HttpChannelChild> self = this;
int32_t bytesRead = mUnreportBytesRead;
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
DebugOnly<nsresult> rv = neckoTarget->Dispatch(
@ -1456,7 +1456,7 @@ mozilla::ipc::IPCResult HttpChannelChild::RecvFinishInterceptedRedirect() {
// The IPDL connection was torn down by a interception logic in
// CompleteRedirectSetup, and we need to call FinishInterceptedRedirect.
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
Unused << neckoTarget->Dispatch(
@ -1705,7 +1705,7 @@ void HttpChannelChild::Redirect1Begin(
mRedirectChannelChild->ConnectParent(registrarId);
}
nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> target = GetNeckoTarget();
MOZ_ASSERT(target);
rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, redirectFlags,
@ -1762,7 +1762,7 @@ void HttpChannelChild::BeginNonIPCRedirect(
}
}
nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> target = GetNeckoTarget();
MOZ_ASSERT(target);
rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, redirectFlag,
@ -1924,7 +1924,7 @@ void HttpChannelChild::ProcessDivertMessages() {
// DivertTo() has been called on parent, so we can now start sending queued
// IPDL messages back to parent listener.
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
nsresult rv =
neckoTarget->Dispatch(NewRunnableMethod("HttpChannelChild::Resume", this,
@ -2183,7 +2183,7 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult aResult) {
RefPtr<InterceptStreamListener> streamListener =
new InterceptStreamListener(redirectedChannel, nullptr);
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
nsCOMPtr<nsIInterceptedBodyCallback> callback =
@ -2358,7 +2358,7 @@ HttpChannelChild::Resume() {
SendResume();
}
if (mCallOnResume) {
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
RefPtr<HttpChannelChild> self = this;
@ -2576,12 +2576,12 @@ nsresult HttpChannelChild::AsyncOpenInternal(nsIStreamListener* aListener) {
return rv;
}
// Assigns an nsIEventTarget to our IPDL actor so that IPC messages are sent to
// the correct DocGroup/TabGroup.
// Assigns an nsISerialEventTarget to our IPDL actor so that IPC messages are
// sent to the correct DocGroup/TabGroup.
void HttpChannelChild::SetEventTarget() {
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
nsCOMPtr<nsIEventTarget> target =
nsCOMPtr<nsISerialEventTarget> target =
nsContentUtils::GetEventTargetByLoadInfo(loadInfo, TaskCategory::Network);
if (!target) {
@ -2596,15 +2596,15 @@ void HttpChannelChild::SetEventTarget() {
}
}
already_AddRefed<nsIEventTarget> HttpChannelChild::GetNeckoTarget() {
nsCOMPtr<nsIEventTarget> target;
already_AddRefed<nsISerialEventTarget> HttpChannelChild::GetNeckoTarget() {
nsCOMPtr<nsISerialEventTarget> target;
{
MutexAutoLock lock(mEventTargetMutex);
target = mNeckoTarget;
}
if (!target) {
target = GetMainThreadEventTarget();
target = GetMainThreadSerialEventTarget();
}
return target.forget();
}
@ -2613,7 +2613,11 @@ already_AddRefed<nsIEventTarget> HttpChannelChild::GetODATarget() {
nsCOMPtr<nsIEventTarget> target;
{
MutexAutoLock lock(mEventTargetMutex);
target = mODATarget ? mODATarget : mNeckoTarget;
if (mODATarget) {
target = mODATarget;
} else {
target = mNeckoTarget;
}
}
if (!target) {
@ -3124,7 +3128,7 @@ HttpChannelChild::OpenAlternativeOutputStream(const nsACString& aType,
return NS_ERROR_NOT_AVAILABLE;
}
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
RefPtr<AltDataOutputStreamChild> stream = new AltDataOutputStreamChild();
@ -3635,7 +3639,7 @@ void HttpChannelChild::TrySendDeletingChannel() {
return;
}
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
DebugOnly<nsresult> rv = neckoTarget->Dispatch(
@ -3650,7 +3654,7 @@ void HttpChannelChild::OnCopyComplete(nsresult aStatus) {
nsCOMPtr<nsIRunnable> runnable = NewRunnableMethod<nsresult>(
"net::HttpBaseChannel::EnsureUploadStreamIsCloneableComplete", this,
&HttpChannelChild::EnsureUploadStreamIsCloneableComplete, aStatus);
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
Unused << neckoTarget->Dispatch(runnable, NS_DISPATCH_NORMAL);
@ -3663,7 +3667,7 @@ nsresult HttpChannelChild::AsyncCallImpl(
RefPtr<nsRunnableMethod<HttpChannelChild>> event =
NewRunnableMethod("net::HttpChannelChild::AsyncCall", this, funcPtr);
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
rv = neckoTarget->Dispatch(event, NS_DISPATCH_NORMAL);
@ -3788,7 +3792,7 @@ void HttpChannelChild::OverrideWithSynthesizedResponse(
mSynthesizedStreamLength = -1;
}
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
nsCOMPtr<nsISerialEventTarget> neckoTarget = GetNeckoTarget();
MOZ_ASSERT(neckoTarget);
rv = nsInputStreamPump::Create(getter_AddRefs(mSynthesizedResponsePump),

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

@ -37,6 +37,7 @@ using mozilla::Telemetry::LABELS_HTTP_CHILD_OMT_STATS;
class nsIEventTarget;
class nsInputStreamPump;
class nsISerialEventTarget;
class nsIInterceptedBodyCallback;
#define HTTP_CHANNEL_CHILD_IID \
@ -208,7 +209,7 @@ class HttpChannelChild final : public PHttpChannelChild,
};
// Get event target for processing network events.
already_AddRefed<nsIEventTarget> GetNeckoTarget() override;
already_AddRefed<nsISerialEventTarget> GetNeckoTarget() override;
virtual mozilla::ipc::IPCResult RecvLogBlockedCORSRequest(
const nsString& aMessage, const nsCString& aCategory) override;

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

@ -13,7 +13,7 @@ namespace mozilla {
namespace net {
WebSocketEventListenerChild::WebSocketEventListenerChild(
uint64_t aInnerWindowID, nsIEventTarget* aTarget)
uint64_t aInnerWindowID, nsISerialEventTarget* aTarget)
: NeckoTargetHolder(aTarget),
mService(WebSocketEventService::GetOrCreate()),
mInnerWindowID(aInnerWindowID) {}

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

@ -21,7 +21,7 @@ class WebSocketEventListenerChild final : public PWebSocketEventListenerChild,
NS_INLINE_DECL_REFCOUNTING(WebSocketEventListenerChild)
explicit WebSocketEventListenerChild(uint64_t aInnerWindowID,
nsIEventTarget* aTarget);
nsISerialEventTarget* aTarget);
mozilla::ipc::IPCResult RecvWebSocketCreated(
const uint32_t& aWebSocketSerialID, const nsString& aURI,

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

@ -424,7 +424,7 @@ void DataChannelConnection::DestroyOnSTS(struct socket* aMasterSocket,
Maybe<RefPtr<DataChannelConnection>> DataChannelConnection::Create(
DataChannelConnection::DataConnectionListener* aListener,
nsIEventTarget* aTarget, MediaTransportHandler* aHandler,
nsISerialEventTarget* aTarget, MediaTransportHandler* aHandler,
const uint16_t aLocalPort, const uint16_t aNumStreams,
const Maybe<uint64_t>& aMaxMessageSize) {
ASSERT_WEBRTC(NS_IsMainThread());
@ -438,7 +438,7 @@ Maybe<RefPtr<DataChannelConnection>> DataChannelConnection::Create(
DataChannelConnection::DataChannelConnection(
DataChannelConnection::DataConnectionListener* aListener,
nsIEventTarget* aTarget, MediaTransportHandler* aHandler)
nsISerialEventTarget* aTarget, MediaTransportHandler* aHandler)
: NeckoTargetHolder(aTarget),
mLock("netwerk::sctp::DataChannelConnection"),
mListener(aListener),

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

@ -144,7 +144,7 @@ class DataChannelConnection final : public net::NeckoTargetHolder
// Create a new DataChannel Connection
// Must be called on Main thread
static Maybe<RefPtr<DataChannelConnection>> Create(
DataConnectionListener* aListener, nsIEventTarget* aTarget,
DataConnectionListener* aListener, nsISerialEventTarget* aTarget,
MediaTransportHandler* aHandler, const uint16_t aLocalPort,
const uint16_t aNumStreams, const Maybe<uint64_t>& aMaxMessageSize);
@ -233,7 +233,7 @@ class DataChannelConnection final : public net::NeckoTargetHolder
private:
DataChannelConnection(DataConnectionListener* aListener,
nsIEventTarget* aTarget,
nsISerialEventTarget* aTarget,
MediaTransportHandler* aHandler);
bool Init(const uint16_t aLocalPort, const uint16_t aNumStreams,
@ -557,7 +557,7 @@ class DataChannel {
nsCString mRecvBuffer;
nsTArray<UniquePtr<BufferedOutgoingMsg>>
mBufferedData; // GUARDED_BY(mConnection->mLock)
nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
nsCOMPtr<nsISerialEventTarget> mMainThreadEventTarget;
mutable Mutex mStatsLock; // protects mTrafficCounters
TrafficCounters mTrafficCounters;
};