Bug 1435263 - Get rid of WorkerPrivateParent template - part 1 - BusyCount and ParentStatus, r=bkelly

This commit is contained in:
Andrea Marchesini 2018-02-08 09:33:32 +01:00
parent 2dfbe16467
commit 6c62c6ebec
2 changed files with 67 additions and 60 deletions

View File

@ -1559,8 +1559,8 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
mCondVar(mMutex, "WorkerPrivateParent CondVar"),
mParent(aParent), mScriptURL(aScriptURL),
mWorkerName(aWorkerName),
mLoadingWorkerScript(false), mBusyCount(0), mParentWindowPausedDepth(0),
mParentStatus(Pending), mParentFrozen(false),
mLoadingWorkerScript(false), mParentWindowPausedDepth(0),
mParentFrozen(false),
mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false),
mIsSecureContext(false), mWorkerType(aWorkerType),
mCreationTimeStamp(TimeStamp::Now()),
@ -1636,6 +1636,8 @@ WorkerPrivateParent<Derived>::Traverse(nsCycleCollectionTraversalCallback& aCb)
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
// The WorkerPrivate::mParentEventTargetRef has a reference to the exposed
// Worker object, which is really held by the worker thread. We traverse this
// reference if and only if our busy count is zero and we have not released
@ -1643,7 +1645,7 @@ WorkerPrivateParent<Derived>::Traverse(nsCycleCollectionTraversalCallback& aCb)
// break cycles involving the Worker and begin shutting it down (which does
// happen in unlink) but ensures that the WorkerPrivate won't be deleted
// before we're done shutting down the thread.
if (!mBusyCount && !mMainThreadObjectsForgotten) {
if (!self->mBusyCount && !mMainThreadObjectsForgotten) {
nsCycleCollectionTraversalCallback& cb = aCb;
WorkerPrivateParent<Derived>* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentEventTargetRef);
@ -1827,11 +1829,12 @@ WorkerPrivateParent<Derived>::Start()
// May be called on any thread!
{
MutexAutoLock lock(mMutex);
WorkerPrivate* self = ParentAsWorkerPrivate();
NS_ASSERTION(mParentStatus != Running, "How can this be?!");
NS_ASSERTION(self->mParentStatus != Running, "How can this be?!");
if (mParentStatus == Pending) {
mParentStatus = Running;
if (self->mParentStatus == Pending) {
self->mParentStatus = Running;
return true;
}
}
@ -1845,17 +1848,18 @@ bool
WorkerPrivateParent<Derived>::NotifyPrivate(WorkerStatus aStatus)
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
bool pending;
{
MutexAutoLock lock(mMutex);
if (mParentStatus >= aStatus) {
if (self->mParentStatus >= aStatus) {
return true;
}
pending = mParentStatus == Pending;
mParentStatus = aStatus;
pending = self->mParentStatus == Pending;
self->mParentStatus = aStatus;
}
if (IsSharedWorker()) {
@ -1866,8 +1870,6 @@ WorkerPrivateParent<Derived>::NotifyPrivate(WorkerStatus aStatus)
}
if (pending) {
WorkerPrivate* self = ParentAsWorkerPrivate();
#ifdef DEBUG
{
// Fake a thread here just so that our assertions don't go off for no
@ -1902,6 +1904,7 @@ bool
WorkerPrivateParent<Derived>::Freeze(nsPIDOMWindowInner* aWindow)
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
// Shared workers are only frozen if all of their owning documents are
// frozen. It can happen that mSharedWorkers is empty but this thread has
@ -1928,17 +1931,17 @@ WorkerPrivateParent<Derived>::Freeze(nsPIDOMWindowInner* aWindow)
}
}
if (!allFrozen || mParentFrozen) {
if (!allFrozen || self->mParentFrozen) {
return true;
}
}
mParentFrozen = true;
self->mParentFrozen = true;
{
MutexAutoLock lock(mMutex);
if (mParentStatus >= Terminating) {
if (self->mParentStatus >= Terminating) {
return true;
}
}
@ -1959,6 +1962,7 @@ bool
WorkerPrivateParent<Derived>::Thaw(nsPIDOMWindowInner* aWindow)
{
AssertIsOnParentThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
MOZ_ASSERT(mParentFrozen);
@ -2000,7 +2004,7 @@ WorkerPrivateParent<Derived>::Thaw(nsPIDOMWindowInner* aWindow)
{
MutexAutoLock lock(mMutex);
if (mParentStatus >= Terminating) {
if (self->mParentStatus >= Terminating) {
return true;
}
}
@ -2043,6 +2047,7 @@ void
WorkerPrivateParent<Derived>::ParentWindowResumed()
{
AssertIsOnMainThread();
WorkerPrivate* self = ParentAsWorkerPrivate();
MOZ_ASSERT(mParentWindowPausedDepth > 0);
MOZ_ASSERT_IF(IsDedicatedWorker(), mParentWindowPausedDepth == 1);
@ -2054,7 +2059,7 @@ WorkerPrivateParent<Derived>::ParentWindowResumed()
{
MutexAutoLock lock(mMutex);
if (mParentStatus >= Terminating) {
if (self->mParentStatus >= Terminating) {
return;
}
}
@ -2078,17 +2083,17 @@ bool
WorkerPrivateParent<Derived>::Close()
{
mMutex.AssertCurrentThreadOwns();
WorkerPrivate* self = ParentAsWorkerPrivate();
if (mParentStatus < Closing) {
mParentStatus = Closing;
if (self->mParentStatus < Closing) {
self->mParentStatus = Closing;
}
return true;
}
template <class Derived>
bool
WorkerPrivateParent<Derived>::ModifyBusyCount(bool aIncrease)
WorkerPrivate::ModifyBusyCount(bool aIncrease)
{
AssertIsOnParentThread();
@ -2768,6 +2773,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
WorkerEventTarget::Behavior::Hybrid))
, mErrorHandlerRecursionCount(0)
, mNextTimeoutId(1)
, mParentStatus(Pending)
, mStatus(Pending)
, mFrozen(false)
, mTimerRunning(false)
@ -2779,6 +2785,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
, mWorkerScriptExecutedSuccessfully(false)
, mFetchHandlerWasAdded(false)
, mOnLine(false)
, mBusyCount(0)
{
if (aParent) {
aParent->AssertIsOnWorkerThread();

View File

@ -151,14 +151,9 @@ private:
// thread as SharedWorkers are always top-level).
nsTArray<RefPtr<SharedWorker>> mSharedWorkers;
// This is touched on parent thread only, but it can be read on a different
// thread before crashing because hanging.
Atomic<uint64_t> mBusyCount;
// SharedWorkers may have multiple windows paused, so this must be
// a count instead of just a boolean.
uint32_t mParentWindowPausedDepth;
WorkerStatus mParentStatus;
bool mParentFrozen;
bool mIsChromeWorker;
bool mMainThreadObjectsForgotten;
@ -304,9 +299,6 @@ public:
bool
Close();
bool
ModifyBusyCount(bool aIncrease);
bool
ProxyReleaseMainThreadObjects();
@ -374,30 +366,6 @@ public:
return mParentWindowPausedDepth > 0;
}
bool
IsAcceptingEvents()
{
AssertIsOnParentThread();
MutexAutoLock lock(mMutex);
return mParentStatus < Terminating;
}
WorkerStatus
ParentStatusProtected()
{
AssertIsOnParentThread();
MutexAutoLock lock(mMutex);
return mParentStatus;
}
WorkerStatus
ParentStatus() const
{
mMutex.AssertCurrentThreadOwns();
return mParentStatus;
}
nsIScriptContext*
GetScriptContext() const
{
@ -854,14 +822,6 @@ public:
bool
PrincipalIsValid() const;
#endif
// This method is used by RuntimeService to know what is going wrong the
// shutting down.
uint32_t
BusyCount()
{
return mBusyCount;
}
};
class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
@ -944,6 +904,7 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
TimeStamp mKillTime;
uint32_t mErrorHandlerRecursionCount;
uint32_t mNextTimeoutId;
WorkerStatus mParentStatus;
WorkerStatus mStatus;
UniquePtr<ClientSource> mClientSource;
bool mFrozen;
@ -957,6 +918,10 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
bool mFetchHandlerWasAdded;
bool mOnLine;
// This is touched on parent thread only, but it can be read on a different
// thread before crashing because hanging.
Atomic<uint64_t> mBusyCount;
protected:
~WorkerPrivate();
@ -1371,6 +1336,30 @@ public:
PerformanceStorage*
GetPerformanceStorage();
bool
IsAcceptingEvents()
{
AssertIsOnParentThread();
MutexAutoLock lock(mMutex);
return mParentStatus < Terminating;
}
WorkerStatus
ParentStatusProtected()
{
AssertIsOnParentThread();
MutexAutoLock lock(mMutex);
return mParentStatus;
}
WorkerStatus
ParentStatus() const
{
mMutex.AssertCurrentThreadOwns();
return mParentStatus;
}
Worker*
ParentEventTargetRef() const
{
@ -1386,6 +1375,17 @@ public:
mParentEventTargetRef = aParentEventTargetRef;
}
bool
ModifyBusyCount(bool aIncrease);
// This method is used by RuntimeService to know what is going wrong the
// shutting down.
uint32_t
BusyCount()
{
return mBusyCount;
}
private:
WorkerPrivate(WorkerPrivate* aParent,
const nsAString& aScriptURL, bool aIsChromeWorker,