1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "nsILabelableRunnable.h" 8 9 #include "mozilla/Scheduler.h" 10 #include "mozilla/SchedulerGroup.h" 11 IsReadyToRun()12bool nsILabelableRunnable::IsReadyToRun() { 13 MOZ_ASSERT(mozilla::Scheduler::AnyEventRunning()); 14 MOZ_ASSERT(!mozilla::Scheduler::UnlabeledEventRunning()); 15 SchedulerGroupSet groups; 16 if (!GetAffectedSchedulerGroups(groups)) { 17 // it can not be labeled right now. 18 return false; 19 } 20 21 if (groups.mSingle) { 22 MOZ_ASSERT(groups.mMulti.isNothing()); 23 return !groups.mSingle->IsRunning(); 24 } 25 26 if (groups.mMulti.isSome()) { 27 MOZ_ASSERT(!groups.mSingle); 28 for (auto iter = groups.mMulti.ref().ConstIter(); !iter.Done(); 29 iter.Next()) { 30 if (iter.Get()->GetKey()->IsRunning()) { 31 return false; 32 } 33 } 34 return true; 35 } 36 37 // No affected groups if we are here. Then, it's ready to run. 38 return true; 39 } 40 Put(mozilla::SchedulerGroup * aGroup)41void nsILabelableRunnable::SchedulerGroupSet::Put( 42 mozilla::SchedulerGroup* aGroup) { 43 if (mSingle) { 44 MOZ_ASSERT(mMulti.isNothing()); 45 mMulti.emplace(); 46 auto& multi = mMulti.ref(); 47 multi.PutEntry(mSingle); 48 multi.PutEntry(aGroup); 49 mSingle = nullptr; 50 return; 51 } 52 53 if (mMulti.isSome()) { 54 MOZ_ASSERT(!mSingle); 55 mMulti.ref().PutEntry(aGroup); 56 return; 57 } 58 59 mSingle = aGroup; 60 } 61 Clear()62void nsILabelableRunnable::SchedulerGroupSet::Clear() { 63 mSingle = nullptr; 64 mMulti.reset(); 65 } 66 SetIsRunning(bool aIsRunning)67void nsILabelableRunnable::SchedulerGroupSet::SetIsRunning(bool aIsRunning) { 68 if (mSingle) { 69 MOZ_ASSERT(mMulti.isNothing()); 70 mSingle->SetIsRunning(aIsRunning); 71 return; 72 } 73 74 if (mMulti.isSome()) { 75 MOZ_ASSERT(!mSingle); 76 for (auto iter = mMulti.ref().ConstIter(); !iter.Done(); iter.Next()) { 77 MOZ_ASSERT(iter.Get()->GetKey()->IsRunning() != aIsRunning); 78 iter.Get()->GetKey()->SetIsRunning(aIsRunning); 79 } 80 return; 81 } 82 } 83