Global Metrics
path: .metrics.nexits.sum
old: 0.0
new: 2.0
path: .metrics.nexits.average
old: 0.0
new: 0.3333333333333333
path: .metrics.nargs.average
old: 1.5714285714285714
new: 1.0
path: .metrics.nargs.sum
old: 11.0
new: 6.0
path: .metrics.cognitive.average
old: 0.2857142857142857
new: 0.3333333333333333
path: .metrics.nom.total
old: 7.0
new: 6.0
path: .metrics.nom.functions
old: 7.0
new: 6.0
path: .metrics.cyclomatic.sum
old: 11.0
new: 15.0
path: .metrics.cyclomatic.average
old: 1.1
new: 1.1538461538461535
path: .metrics.mi.mi_sei
old: 44.84405577072875
new: 19.953664502806355
path: .metrics.mi.mi_original
old: 57.14199831306664
new: 38.173241749220864
path: .metrics.mi.mi_visual_studio
old: 33.41637328249511
new: 22.32353318667887
path: .metrics.halstead.n2
old: 59.0
new: 97.0
path: .metrics.halstead.time
old: 1350.5561070242966
new: 3503.7679594837637
path: .metrics.halstead.length
old: 261.0
new: 443.0
path: .metrics.halstead.volume
old: 1620.667328429156
new: 3043.5715707754484
path: .metrics.halstead.N1
old: 143.0
new: 242.0
path: .metrics.halstead.estimated_program_length
old: 405.6792988464764
new: 726.6301075898987
path: .metrics.halstead.purity_ratio
old: 1.554326815503741
new: 1.640248549864331
path: .metrics.halstead.bugs
old: 0.27972771821190956
new: 0.5281419199813144
path: .metrics.halstead.vocabulary
old: 74.0
new: 117.0
path: .metrics.halstead.difficulty
old: 15.0
new: 20.721649484536083
path: .metrics.halstead.n1
old: 15.0
new: 20.0
path: .metrics.halstead.N2
old: 118.0
new: 201.0
path: .metrics.halstead.level
old: 0.06666666666666667
new: 0.04825870646766169
path: .metrics.halstead.effort
old: 24310.00992643734
new: 63067.82327070775
path: .metrics.loc.lloc
old: 16.0
new: 19.0
path: .metrics.loc.cloc
old: 26.0
new: 75.0
path: .metrics.loc.ploc
old: 50.0
new: 111.0
path: .metrics.loc.blank
old: 14.0
new: 38.0
path: .metrics.loc.sloc
old: 90.0
new: 224.0
Spaces Data
Minimal test - lines (129, 135)
path: .spaces[0].spaces[0].spaces[3].metrics.nargs.average
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.nargs.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.cognitive.average
old: 0.0
new: 2.0
path: .spaces[0].spaces[0].spaces[3].metrics.cognitive.sum
old: 0.0
new: 2.0
path: .spaces[0].spaces[0].spaces[3].metrics.cyclomatic.average
old: 1.0
new: 3.0
path: .spaces[0].spaces[0].spaces[3].metrics.cyclomatic.sum
old: 1.0
new: 3.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.bugs
old: 0.009388882548620756
new: 0.024104229172388934
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.estimated_program_length
old: 23.509775004326936
new: 71.27302875388389
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N1
old: 7.0
new: 17.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.difficulty
old: 3.75
new: 5.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.purity_ratio
old: 1.9591479170272448
new: 2.5454653126387106
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.time
old: 8.304820237218406
new: 34.16246884383481
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n2
old: 4.0
new: 11.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.vocabulary
old: 10.0
new: 21.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.volume
old: 39.86313713864835
new: 122.9848878378053
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.level
old: 0.26666666666666666
new: 0.2
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N2
old: 5.0
new: 11.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.effort
old: 149.4867642699313
new: 614.9244391890265
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n1
old: 6.0
new: 10.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.length
old: 12.0
new: 28.0
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_original
old: 133.808130442365
new: 113.76353586477629
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_visual_studio
old: 78.25036867974562
new: 66.5283835466528
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_sei
old: 156.43782660646212
new: 88.73069661230713
path: .spaces[0].spaces[0].spaces[3].metrics.loc.lloc
old: 1.0
new: 4.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.sloc
old: 3.0
new: 7.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.cloc
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.ploc
old: 3.0
new: 7.0
Code
void MaybeResolveShutdown() {
mQueueMonitor.AssertCurrentThreadOwns();
if (mIsShutdown && !mIsRunning) {
mShutdownPromise.ResolveIfExists(true, __func__);
mTarget = nullptr;
}
}
Minimal test - lines (50, 220)
path: .spaces[0].spaces[0].metrics.loc.sloc
old: 72.0
new: 171.0
path: .spaces[0].spaces[0].metrics.loc.cloc
old: 18.0
new: 43.0
path: .spaces[0].spaces[0].metrics.loc.blank
old: 13.0
new: 32.0
path: .spaces[0].spaces[0].metrics.loc.lloc
old: 16.0
new: 19.0
path: .spaces[0].spaces[0].metrics.loc.ploc
old: 41.0
new: 96.0
path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 48.88666839521784
new: 23.277999883061852
path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 35.954374463323596
new: 25.37610653117938
path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 61.48198033228334
new: 43.39314216831674
path: .spaces[0].spaces[0].metrics.cognitive.average
old: 0.2857142857142857
new: 0.3333333333333333
path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 1.125
new: 1.181818181818182
path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 9.0
new: 13.0
path: .spaces[0].spaces[0].metrics.nom.total
old: 7.0
new: 6.0
path: .spaces[0].spaces[0].metrics.nom.functions
old: 7.0
new: 6.0
path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.2788189088537787
new: 0.5190321674676801
path: .spaces[0].spaces[0].metrics.halstead.N2
old: 111.0
new: 187.0
path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 15.70754716981132
new: 21.74418604651163
path: .spaces[0].spaces[0].metrics.halstead.effort
old: 24191.634760023575
new: 61443.12470946438
path: .spaces[0].spaces[0].metrics.halstead.length
old: 253.0
new: 420.0
path: .spaces[0].spaces[0].metrics.halstead.n1
old: 15.0
new: 20.0
path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.431553925003863
new: 1.5216603114336371
path: .spaces[0].spaces[0].metrics.halstead.N1
old: 142.0
new: 233.0
path: .spaces[0].spaces[0].metrics.halstead.time
old: 1343.9797088901987
new: 3413.5069283035764
path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 68.0
new: 106.0
path: .spaces[0].spaces[0].metrics.halstead.n2
old: 53.0
new: 86.0
path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.06366366366366366
new: 0.045989304812834225
path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 362.1831430259773
new: 639.0973308021277
path: .spaces[0].spaces[0].metrics.halstead.volume
old: 1540.1280988363358
new: 2825.7265909165435
path: .spaces[0].spaces[0].metrics.nargs.sum
old: 11.0
new: 6.0
path: .spaces[0].spaces[0].metrics.nargs.average
old: 1.5714285714285714
new: 1.0
path: .spaces[0].spaces[0].metrics.nexits.average
old: 0.0
new: 0.3333333333333333
path: .spaces[0].spaces[0].metrics.nexits.sum
old: 0.0
new: 2.0
Code
class TaskQueue : public AbstractThread, public nsIDirectTaskDispatcher {
class EventTargetWrapper;
public:
explicit TaskQueue(already_AddRefed aTarget,
bool aSupportsTailDispatch = false);
TaskQueue(already_AddRefed aTarget, const char* aName,
bool aSupportsTailDispatch = false);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDIRECTTASKDISPATCHER
TaskDispatcher& TailDispatcher() override;
NS_IMETHOD Dispatch(already_AddRefed aEvent,
uint32_t aFlags) override {
nsCOMPtr runnable = aEvent;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ runnable, aFlags,
NormalDispatch);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
[[nodiscard]] nsresult Dispatch(
already_AddRefed aRunnable,
DispatchReason aReason = NormalDispatch) override {
nsCOMPtr r = aRunnable;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ r, NS_DISPATCH_NORMAL, aReason);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
// So we can access nsIEventTarget::Dispatch(nsIRunnable*, uint32_t aFlags)
using nsIEventTarget::Dispatch;
// Puts the queue in a shutdown state and returns immediately. The queue will
// remain alive at least until all the events are drained, because the Runners
// hold a strong reference to the task queue, and one of them is always held
// by the target event queue when the task queue is non-empty.
//
// The returned promise is resolved when the queue goes empty.
RefPtr BeginShutdown();
// Blocks until all task finish executing.
void AwaitIdle();
// Blocks until the queue is flagged for shutdown and all tasks have finished
// executing.
void AwaitShutdownAndIdle();
bool IsEmpty();
// Returns true if the current thread is currently running a Runnable in
// the task queue.
bool IsCurrentThreadIn() const override;
using nsISerialEventTarget::IsOnCurrentThread;
protected:
virtual ~TaskQueue();
// Blocks until all task finish executing. Called internally by methods
// that need to wait until the task queue is idle.
// mQueueMonitor must be held.
void AwaitIdleLocked();
nsresult DispatchLocked(nsCOMPtr& aRunnable, uint32_t aFlags,
DispatchReason aReason = NormalDispatch);
void MaybeResolveShutdown() {
mQueueMonitor.AssertCurrentThreadOwns();
if (mIsShutdown && !mIsRunning) {
mShutdownPromise.ResolveIfExists(true, __func__);
mTarget = nullptr;
}
}
nsCOMPtr mTarget;
// Monitor that protects the queue and mIsRunning;
Monitor mQueueMonitor;
typedef struct TaskStruct {
nsCOMPtr event;
uint32_t flags;
} TaskStruct;
// Queue of tasks to run.
std::queue mTasks;
// The thread currently running the task queue. We store a reference
// to this so that IsCurrentThreadIn() can tell if the current thread
// is the thread currently running in the task queue.
//
// This may be read on any thread, but may only be written on mRunningThread.
// The thread can't die while we're running in it, and we only use it for
// pointer-comparison with the current thread anyway - so we make it atomic
// and don't refcount it.
Atomic mRunningThread;
// RAII class that gets instantiated for each dispatched task.
class AutoTaskGuard {
public:
explicit AutoTaskGuard(TaskQueue* aQueue)
: mQueue(aQueue), mLastCurrentThread(nullptr) {
// NB: We don't hold the lock to aQueue here. Don't do anything that
// might require it.
MOZ_ASSERT(!mQueue->mTailDispatcher);
mTaskDispatcher.emplace(aQueue,
/* aIsTailDispatcher = */ true);
mQueue->mTailDispatcher = mTaskDispatcher.ptr();
mLastCurrentThread = sCurrentThreadTLS.get();
sCurrentThreadTLS.set(aQueue);
MOZ_ASSERT(mQueue->mRunningThread == nullptr);
mQueue->mRunningThread = PR_GetCurrentThread();
}
~AutoTaskGuard() {
mTaskDispatcher->DrainDirectTasks();
mTaskDispatcher.reset();
MOZ_ASSERT(mQueue->mRunningThread == PR_GetCurrentThread());
mQueue->mRunningThread = nullptr;
sCurrentThreadTLS.set(mLastCurrentThread);
mQueue->mTailDispatcher = nullptr;
}
private:
Maybe mTaskDispatcher;
TaskQueue* mQueue;
AbstractThread* mLastCurrentThread;
};
TaskDispatcher* mTailDispatcher;
// True if we've dispatched an event to the target to execute events from
// the queue.
bool mIsRunning;
// True if we've started our shutdown process.
bool mIsShutdown;
MozPromiseHolder mShutdownPromise;
// The name of this TaskQueue. Useful when debugging dispatch failures.
const char* const mName;
SimpleTaskQueue mDirectTasks;
class Runner : public Runnable {
public:
explicit Runner(TaskQueue* aQueue)
: Runnable("TaskQueue::Runner"), mQueue(aQueue) {}
NS_IMETHOD Run() override;
private:
RefPtr mQueue;
};
};
Minimal test - lines (21, 222)
path: .spaces[0].metrics.nargs.average
old: 1.5714285714285714
new: 1.0
path: .spaces[0].metrics.nargs.sum
old: 11.0
new: 6.0
path: .spaces[0].metrics.halstead.n2
old: 54.0
new: 88.0
path: .spaces[0].metrics.halstead.N2
old: 112.0
new: 191.0
path: .spaces[0].metrics.halstead.volume
old: 1557.673736478433
new: 2924.866288436782
path: .spaces[0].metrics.halstead.bugs
old: 0.27911730365696885
new: 0.5304566357830517
path: .spaces[0].metrics.halstead.n1
old: 15.0
new: 20.0
path: .spaces[0].metrics.halstead.difficulty
old: 15.555555555555555
new: 21.704545454545453
path: .spaces[0].metrics.halstead.effort
old: 24230.48034522007
new: 63482.89330584378
path: .spaces[0].metrics.halstead.vocabulary
old: 69.0
new: 108.0
path: .spaces[0].metrics.halstead.time
old: 1346.1377969566704
new: 3526.8274058802103
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.448499153141
new: 1.5123984857686592
path: .spaces[0].metrics.halstead.estimated_program_length
old: 369.36728405095505
new: 654.8685443378295
path: .spaces[0].metrics.halstead.length
old: 255.0
new: 433.0
path: .spaces[0].metrics.halstead.level
old: 0.0642857142857143
new: 0.04607329842931938
path: .spaces[0].metrics.halstead.N1
old: 143.0
new: 242.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.1111111111111112
new: 1.1666666666666667
path: .spaces[0].metrics.cyclomatic.sum
old: 10.0
new: 14.0
path: .spaces[0].metrics.loc.blank
old: 12.0
new: 35.0
path: .spaces[0].metrics.loc.ploc
old: 43.0
new: 99.0
path: .spaces[0].metrics.loc.sloc
old: 74.0
new: 202.0
path: .spaces[0].metrics.loc.cloc
old: 19.0
new: 68.0
path: .spaces[0].metrics.loc.lloc
old: 16.0
new: 19.0
path: .spaces[0].metrics.cognitive.average
old: 0.2857142857142857
new: 0.3333333333333333
path: .spaces[0].metrics.nexits.average
old: 0.0
new: 0.3333333333333333
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 2.0
path: .spaces[0].metrics.nom.total
old: 7.0
new: 6.0
path: .spaces[0].metrics.nom.functions
old: 7.0
new: 6.0
path: .spaces[0].metrics.mi.mi_sei
old: 48.300994327796566
new: 22.973762892370672
path: .spaces[0].metrics.mi.mi_original
old: 60.74921176783758
new: 40.28484226671664
path: .spaces[0].metrics.mi.mi_visual_studio
old: 35.525854834992735
new: 23.558387290477565
Code
namespace mozilla {
typedef MozPromise ShutdownPromise;
// Abstracts executing runnables in order on an arbitrary event target. The
// runnables dispatched to the TaskQueue will be executed in the order in which
// they're received, and are guaranteed to not be executed concurrently.
// They may be executed on different threads, and a memory barrier is used
// to make this threadsafe for objects that aren't already threadsafe.
//
// Note, since a TaskQueue can also be converted to an nsIEventTarget using
// WrapAsEventTarget() its possible to construct a hierarchy of TaskQueues.
// Consider these three TaskQueues:
//
// TQ1 dispatches to the main thread
// TQ2 dispatches to TQ1
// TQ3 dispatches to TQ1
//
// This ensures there is only ever a single runnable from the entire chain on
// the main thread. It also ensures that TQ2 and TQ3 only have a single
// runnable in TQ1 at any time.
//
// This arrangement lets you prioritize work by dispatching runnables directly
// to TQ1. You can issue many runnables for important work. Meanwhile the TQ2
// and TQ3 work will always execute at most one runnable and then yield.
//
// A TaskQueue does not require explicit shutdown, however it provides a
// BeginShutdown() method that places TaskQueue in a shut down state and returns
// a promise that gets resolved once all pending tasks have completed
class TaskQueue : public AbstractThread, public nsIDirectTaskDispatcher {
class EventTargetWrapper;
public:
explicit TaskQueue(already_AddRefed aTarget,
bool aSupportsTailDispatch = false);
TaskQueue(already_AddRefed aTarget, const char* aName,
bool aSupportsTailDispatch = false);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDIRECTTASKDISPATCHER
TaskDispatcher& TailDispatcher() override;
NS_IMETHOD Dispatch(already_AddRefed aEvent,
uint32_t aFlags) override {
nsCOMPtr runnable = aEvent;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ runnable, aFlags,
NormalDispatch);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
[[nodiscard]] nsresult Dispatch(
already_AddRefed aRunnable,
DispatchReason aReason = NormalDispatch) override {
nsCOMPtr r = aRunnable;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ r, NS_DISPATCH_NORMAL, aReason);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
// So we can access nsIEventTarget::Dispatch(nsIRunnable*, uint32_t aFlags)
using nsIEventTarget::Dispatch;
// Puts the queue in a shutdown state and returns immediately. The queue will
// remain alive at least until all the events are drained, because the Runners
// hold a strong reference to the task queue, and one of them is always held
// by the target event queue when the task queue is non-empty.
//
// The returned promise is resolved when the queue goes empty.
RefPtr BeginShutdown();
// Blocks until all task finish executing.
void AwaitIdle();
// Blocks until the queue is flagged for shutdown and all tasks have finished
// executing.
void AwaitShutdownAndIdle();
bool IsEmpty();
// Returns true if the current thread is currently running a Runnable in
// the task queue.
bool IsCurrentThreadIn() const override;
using nsISerialEventTarget::IsOnCurrentThread;
protected:
virtual ~TaskQueue();
// Blocks until all task finish executing. Called internally by methods
// that need to wait until the task queue is idle.
// mQueueMonitor must be held.
void AwaitIdleLocked();
nsresult DispatchLocked(nsCOMPtr& aRunnable, uint32_t aFlags,
DispatchReason aReason = NormalDispatch);
void MaybeResolveShutdown() {
mQueueMonitor.AssertCurrentThreadOwns();
if (mIsShutdown && !mIsRunning) {
mShutdownPromise.ResolveIfExists(true, __func__);
mTarget = nullptr;
}
}
nsCOMPtr mTarget;
// Monitor that protects the queue and mIsRunning;
Monitor mQueueMonitor;
typedef struct TaskStruct {
nsCOMPtr event;
uint32_t flags;
} TaskStruct;
// Queue of tasks to run.
std::queue mTasks;
// The thread currently running the task queue. We store a reference
// to this so that IsCurrentThreadIn() can tell if the current thread
// is the thread currently running in the task queue.
//
// This may be read on any thread, but may only be written on mRunningThread.
// The thread can't die while we're running in it, and we only use it for
// pointer-comparison with the current thread anyway - so we make it atomic
// and don't refcount it.
Atomic mRunningThread;
// RAII class that gets instantiated for each dispatched task.
class AutoTaskGuard {
public:
explicit AutoTaskGuard(TaskQueue* aQueue)
: mQueue(aQueue), mLastCurrentThread(nullptr) {
// NB: We don't hold the lock to aQueue here. Don't do anything that
// might require it.
MOZ_ASSERT(!mQueue->mTailDispatcher);
mTaskDispatcher.emplace(aQueue,
/* aIsTailDispatcher = */ true);
mQueue->mTailDispatcher = mTaskDispatcher.ptr();
mLastCurrentThread = sCurrentThreadTLS.get();
sCurrentThreadTLS.set(aQueue);
MOZ_ASSERT(mQueue->mRunningThread == nullptr);
mQueue->mRunningThread = PR_GetCurrentThread();
}
~AutoTaskGuard() {
mTaskDispatcher->DrainDirectTasks();
mTaskDispatcher.reset();
MOZ_ASSERT(mQueue->mRunningThread == PR_GetCurrentThread());
mQueue->mRunningThread = nullptr;
sCurrentThreadTLS.set(mLastCurrentThread);
mQueue->mTailDispatcher = nullptr;
}
private:
Maybe mTaskDispatcher;
TaskQueue* mQueue;
AbstractThread* mLastCurrentThread;
};
TaskDispatcher* mTailDispatcher;
// True if we've dispatched an event to the target to execute events from
// the queue.
bool mIsRunning;
// True if we've started our shutdown process.
bool mIsShutdown;
MozPromiseHolder mShutdownPromise;
// The name of this TaskQueue. Useful when debugging dispatch failures.
const char* const mName;
SimpleTaskQueue mDirectTasks;
class Runner : public Runnable {
public:
explicit Runner(TaskQueue* aQueue)
: Runnable("TaskQueue::Runner"), mQueue(aQueue) {}
NS_IMETHOD Run() override;
private:
RefPtr mQueue;
};
};
} // namespace mozilla
Minimal test - lines (142, 145)
path: .spaces[0].spaces[0].spaces[4].metrics.cyclomatic.average
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.cyclomatic.sum
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.cognitive.average
old: 2.0
new: null
path: .spaces[0].spaces[0].spaces[4].metrics.cognitive.sum
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_sei
old: 85.91942054961967
new: 111.37444718573404
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_original
old: 87.23588298945288
new: 129.60014002899223
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_visual_studio
old: 51.01513625114203
new: 75.78955557251007
path: .spaces[0].spaces[0].spaces[4].metrics.nargs.sum
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.nargs.average
old: 2.0
new: null
path: .spaces[0].spaces[0].spaces[4].metrics.nexits.average
old: 0.0
new: null
path: .spaces[0].spaces[0].spaces[4].metrics.nom.total
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.nom.functions
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.estimated_program_length
old: 142.09567279432156
new: 23.21928094887362
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.time
old: 303.33075549136083
new: 5.075167922744582
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.level
old: 0.09504132231404958
new: 0.4
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.difficulty
old: 10.521739130434783
new: 2.5
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.length
old: 102.0
new: 11.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.n1
old: 11.0
new: 5.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.purity_ratio
old: 1.393094831316878
new: 2.110843722624874
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.bugs
old: 0.10335656004826754
new: 0.006761255684837643
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.n2
old: 23.0
new: 5.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N2
old: 44.0
new: 5.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N1
old: 58.0
new: 6.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.volume
old: 518.9212098075346
new: 36.541209043760986
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.vocabulary
old: 34.0
new: 10.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.effort
old: 5459.953598844495
new: 91.35302260940249
path: .spaces[0].spaces[0].spaces[4].metrics.loc.blank
old: 3.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.lloc
old: 7.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.sloc
old: 23.0
new: 4.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.cloc
old: 6.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.ploc
old: 14.0
new: 4.0
Code
typedef struct TaskStruct {
nsCOMPtr event;
uint32_t flags;
} TaskStruct;
Minimal test - lines (65, 77)
path: .spaces[0].spaces[0].spaces[1].metrics.nargs.average
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[1].metrics.nargs.sum
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N2
old: 3.0
new: 17.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N1
old: 4.0
new: 18.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.vocabulary
old: 7.0
new: 22.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.difficulty
old: 2.0
new: 5.884615384615385
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.time
old: 2.1834982727114696
new: 51.02618871325369
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.bugs
old: 0.0038532659414573967
new: 0.031496031486345645
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.level
old: 0.5
new: 0.1699346405228758
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n1
old: 4.0
new: 9.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.purity_ratio
old: 1.8221267860233523
new: 2.189572609966143
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.length
old: 7.0
new: 35.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.effort
old: 39.302968908806456
new: 918.4713968385664
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n2
old: 3.0
new: 13.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: 12.754887502163468
new: 76.63504134881501
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.volume
old: 19.651484454403228
new: 156.0801066523054
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_original
old: 137.4860859464573
new: 102.9558996350324
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_sei
old: 161.74399477282634
new: 113.9165496360271
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: 80.40121985172942
new: 60.208128441539415
path: .spaces[0].spaces[0].spaces[1].metrics.nexits.average
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.lloc
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.cloc
old: 1.0
new: 5.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.ploc
old: 2.0
new: 9.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.sloc
old: 3.0
new: 13.0
Code
NS_IMETHOD Dispatch(already_AddRefed aEvent,
uint32_t aFlags) override {
nsCOMPtr runnable = aEvent;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ runnable, aFlags,
NormalDispatch);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
Minimal test - lines (79, 91)
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.length
old: 48.0
new: 38.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.difficulty
old: 7.7
new: 5.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.time
old: 96.51569554583044
new: 48.3968263965011
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.level
old: 0.12987012987012986
new: 0.2
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.purity_ratio
old: 2.0136897237320426
new: 2.3157894736842106
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N1
old: 27.0
new: 18.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.volume
old: 225.6211064707724
new: 174.2285750274039
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.effort
old: 1737.2825198249477
new: 871.1428751370197
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n2
old: 15.0
new: 16.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.estimated_program_length
old: 96.65710673913804
new: 88.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N2
old: 21.0
new: 20.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.vocabulary
old: 26.0
new: 24.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n1
old: 11.0
new: 8.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.bugs
old: 0.04817174498000614
new: 0.030404533049442024
path: .spaces[0].spaces[0].spaces[2].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.nexits.average
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.sloc
old: 11.0
new: 13.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.blank
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.ploc
old: 6.0
new: 9.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.cloc
old: 4.0
new: 5.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.lloc
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_visual_studio
old: 60.67019871620557
new: 59.87362944924398
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_original
old: 103.74603980471151
new: 102.3839063582072
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_sei
old: 114.28101564363251
new: 113.09133777212956
Code
[[nodiscard]] nsresult Dispatch(
already_AddRefed aRunnable,
DispatchReason aReason = NormalDispatch) override {
nsCOMPtr r = aRunnable;
{
MonitorAutoLock mon(mQueueMonitor);
return DispatchLocked(/* passed by ref */ r, NS_DISPATCH_NORMAL, aReason);
}
// If the ownership of |r| is not transferred in DispatchLocked() due to
// dispatch failure, it will be deleted here outside the lock. We do so
// since the destructor of the runnable might access TaskQueue and result
// in deadlocks.
}
Minimal test - lines (51, 51)
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 7.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 12.754887502163468
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.8221267860233523
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 4.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 19.651484454403228
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 2.1834982727114696
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 39.302968908806456
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 7.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.0038532659414573967
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: 0.5
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 4.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: 137.4860859464573
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 80.40121985172942
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: 161.74399477282634
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.loc.sloc
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.ploc
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.cloc
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.nexits.average
old: 0.0
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: 1.0
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.cognitive.average
old: 0.0
new: null
path: .spaces[0].spaces[0].spaces[0].metrics.nom.total
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.nom.functions
old: 1.0
new: 0.0
Code
class EventTargetWrapper;
Minimal test - lines (211, 219)
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.time
old: 46.62735389278164
new: 42.38850353889241
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.bugs
old: 0.029658846884227635
new: 0.027832943532684742
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.purity_ratio
old: 1.591797727666085
new: 1.7509775004326935
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.volume
old: 134.88627376126118
new: 122.62388523751017
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.effort
old: 839.2923700700695
new: 762.9930637000633
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.N1
old: 19.0
new: 16.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.length
old: 33.0
new: 30.0
path: .spaces[0].spaces[0].spaces[6].metrics.cyclomatic.sum
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_visual_studio
old: 66.51649657884488
new: 64.29095224950674
path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_original
old: 113.74320914982474
new: 109.93752834665652
path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_sei
old: 125.3293992247795
new: 83.10911468010737
path: .spaces[0].spaces[0].spaces[6].metrics.loc.cloc
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[6].metrics.loc.ploc
old: 4.0
new: 8.0
path: .spaces[0].spaces[0].spaces[6].metrics.loc.sloc
old: 7.0
new: 9.0
path: .spaces[0].spaces[0].spaces[6].metrics.loc.lloc
old: 2.0
new: 0.0
Code
class Runner : public Runnable {
public:
explicit Runner(TaskQueue* aQueue)
: Runnable("TaskQueue::Runner"), mQueue(aQueue) {}
NS_IMETHOD Run() override;
private:
RefPtr mQueue;
};
Minimal test - lines (161, 194)
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N1
old: 17.0
new: 68.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.purity_ratio
old: 1.6972127135121615
new: 1.2112837161506158
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.length
old: 34.0
new: 125.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.n1
old: 7.0
new: 14.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.bugs
old: 0.027927562968321624
new: 0.1719920577434781
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.estimated_program_length
old: 57.70523225941349
new: 151.41046451882698
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.effort
old: 766.8871161743452
new: 11720.454974860697
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.n2
old: 11.0
new: 22.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.time
old: 42.604839787463625
new: 651.136387492261
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.vocabulary
old: 18.0
new: 36.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.difficulty
old: 5.409090909090909
new: 18.136363636363637
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.level
old: 0.18487394957983191
new: 0.05513784461152882
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N2
old: 17.0
new: 57.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.volume
old: 141.7774500490386
new: 646.240625180289
path: .spaces[0].spaces[0].spaces[5].metrics.nargs.sum
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[5].metrics.nargs.average
old: 3.0
new: 0.5
path: .spaces[0].spaces[0].spaces[5].metrics.cyclomatic.sum
old: 1.0
new: 3.0
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_visual_studio
old: 66.36497719023775
new: 46.510447673239774
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_sei
old: 115.7564091601054
new: 61.55170262408128
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_original
old: 113.48411099530654
new: 79.53286552124001
path: .spaces[0].spaces[0].spaces[5].metrics.nom.functions
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[5].metrics.nom.total
old: 1.0
new: 2.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.cloc
old: 1.0
new: 3.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.blank
old: 0.0
new: 5.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.ploc
old: 6.0
new: 26.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.lloc
old: 3.0
new: 13.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.sloc
old: 7.0
new: 34.0
Code
class AutoTaskGuard {
public:
explicit AutoTaskGuard(TaskQueue* aQueue)
: mQueue(aQueue), mLastCurrentThread(nullptr) {
// NB: We don't hold the lock to aQueue here. Don't do anything that
// might require it.
MOZ_ASSERT(!mQueue->mTailDispatcher);
mTaskDispatcher.emplace(aQueue,
/* aIsTailDispatcher = */ true);
mQueue->mTailDispatcher = mTaskDispatcher.ptr();
mLastCurrentThread = sCurrentThreadTLS.get();
sCurrentThreadTLS.set(aQueue);
MOZ_ASSERT(mQueue->mRunningThread == nullptr);
mQueue->mRunningThread = PR_GetCurrentThread();
}
~AutoTaskGuard() {
mTaskDispatcher->DrainDirectTasks();
mTaskDispatcher.reset();
MOZ_ASSERT(mQueue->mRunningThread == PR_GetCurrentThread());
mQueue->mRunningThread = nullptr;
sCurrentThreadTLS.set(mLastCurrentThread);
mQueue->mTailDispatcher = nullptr;
}
private:
Maybe mTaskDispatcher;
TaskQueue* mQueue;
AbstractThread* mLastCurrentThread;
};